-
Notifications
You must be signed in to change notification settings - Fork 1
/
dirent.c
124 lines (102 loc) · 2.48 KB
/
dirent.c
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// dirent.c -- Directory Entry
#include <stdlib.h>
#include <string.h>
#include "dirent.h"
#include "region.h"
#include "util.h"
static struct dirent invalid_dirent_s = {};
dirent invalid_dirent = &invalid_dirent_s;
dirent
make_dirent(uint32_t *key, uint8_t len, uint8_t rank)
{
dirent d;
d = malloc(sizeof(struct dirent) + sizeof(struct rdesc) * len);
if (!d) return warn("malloc"), (dirent) 0;
d->len = len;
d->num_copies = 0;
d->key[0] = key[0];
d->key[1] = key[1];
d->key[2] = key[2];
memset(d->rdescs, 0, sizeof(struct rdesc) * len);
dirent_set_rank(d, rank);
return d;
}
dirent
copy_dirent(dirent d, uint8_t new_len)
{
dirent nd;
nd = malloc(sizeof(struct dirent) + sizeof(struct rdesc) * new_len);
if (!nd) return warn("malloc"), (dirent) 0;
nd->len = new_len;
nd->key[0] = d->key[0];
nd->key[1] = d->key[1];
nd->key[2] = d->key[2];
int common = min(d->len, new_len);
for (int i = 0; i < common; i++) {
nd->rdescs[i] = d->rdescs[i];
}
memset(nd->rdescs + common, 0, sizeof(struct rdesc) * (new_len - common));
return nd;
}
int
dirent_matches(dirent d, uint32_t *key)
{
if (!d) return 0;
return d->key[0] == key[0] && d->key[1] == key[1] && d->key[2] == key[2];
}
void
dirent_set_rdesc_local(dirent d, int i, region r, blob b)
{
rdesc_local desc = (rdesc_local) &d->rdescs[i];
desc->flags |= RDESC_LOCAL;
//desc->flags &= ~RDESC_REMOTE;
desc->reg = r->id;
desc->off = region_blob_offset(r, b);
}
rdesc_local
dirent_get_rdesc_local(dirent d)
{
int i;
for (i = 0; i < d->len; i++) {
if (d->rdescs[i].flags & RDESC_LOCAL) break;
}
if (i >= d->len) return 0;
return (rdesc_local) &d->rdescs[i];
}
int
dirent_has_remote(dirent d, in_addr_t addr, uint16_t port)
{
for (int i = 0; i < d->len; i++) {
rdesc rd = d->rdescs + i;
if (rd->flags & RDESC_REMOTE &&
rd->b == addr && rd->a == port) return 1;
}
return 0;
}
int
dirent_add_remote(dirent d, in_addr_t addr, uint16_t port)
{
for (int i = 0; i < d->len; i++) {
rdesc rd = d->rdescs + i;
if (!rd->flags) {
rd->flags |= RDESC_REMOTE;
rd->a = port;
rd->b = addr;
return 0;
}
}
return -1;
}
uint8_t
dirent_get_rank(dirent d)
{
if (!d) return 3;
return d->rank;
}
void
dirent_set_rank(dirent d, uint8_t rank)
{
if (!d) return;
if (rank > 3) rank = 3;
d->rank = rank;
}