Commit d801eb11 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp Committed by Martin Blix Grydeland

Introduce '-' records in VSM _.index files, to reduce VFS workload.

parent 3f436c0c
......@@ -113,6 +113,8 @@ struct vsmw {
struct vsb *vsb;
pid_t pid;
time_t birth;
uint64_t nsegs;
uint64_t nsubs;
};
/*--------------------------------------------------------------------*/
......@@ -127,12 +129,14 @@ vsmw_idx_head(const struct vsmw *vsmw, int fd)
}
static void
vsmw_fmt_index(const struct vsmw *vsmw, const struct vsmwseg *seg)
vsmw_fmt_index(const struct vsmw *vsmw, const struct vsmwseg *seg, char act)
{
CHECK_OBJ_NOTNULL(vsmw, VSMW_MAGIC);
CHECK_OBJ_NOTNULL(seg, VSMWSEG_MAGIC);
VSB_printf(vsmw->vsb, "+ %s %zu %zu %s %s\n",
AN(seg->cluster);
VSB_printf(vsmw->vsb, "%c %s %zu %zu %s %s\n",
act,
seg->cluster->fn,
seg->off,
seg->len,
......@@ -166,20 +170,33 @@ vsmw_mkent(const struct vsmw *vsmw, const char *pfx)
/*--------------------------------------------------------------------*/
static void
vsmw_addseg(struct vsmw *vsmw, struct vsmwseg *seg)
vsmw_append_record(struct vsmw *vsmw, struct vsmwseg *seg, char act)
{
int fd;
ssize_t s;
VTAILQ_INSERT_TAIL(&vsmw->segs, seg, list);
CHECK_OBJ_NOTNULL(vsmw, VSMW_MAGIC);
CHECK_OBJ_NOTNULL(seg, VSMWSEG_MAGIC);
fd = openat(vsmw->vdirfd, vsmw->idx, O_APPEND | O_WRONLY);
assert(fd >= 0);
VSB_clear(vsmw->vsb);
vsmw_fmt_index(vsmw, seg);
vsmw_fmt_index(vsmw, seg, act);
AZ(VSB_finish(vsmw->vsb));
s = write(fd, VSB_data(vsmw->vsb), VSB_len(vsmw->vsb));
assert(s == VSB_len(vsmw->vsb));
assert(s == VSB_len(vsmw->vsb)); // XXX handle ENOSPC? #2764
AZ(close(fd));
vsmw->nsegs++;
}
/*--------------------------------------------------------------------*/
static void
vsmw_addseg(struct vsmw *vsmw, struct vsmwseg *seg)
{
VTAILQ_INSERT_TAIL(&vsmw->segs, seg, list);
vsmw_append_record(vsmw, seg, '+');
vsmw->nsegs++;
}
/*--------------------------------------------------------------------*/
......@@ -190,16 +207,19 @@ vsmw_delseg(struct vsmw *vsmw, struct vsmwseg *seg, int fixidx)
char *t = NULL;
ssize_t s;
int fd;
struct vsmwseg *s2;
CHECK_OBJ_NOTNULL(vsmw, VSMW_MAGIC);
CHECK_OBJ_NOTNULL(seg, VSMWSEG_MAGIC);
VTAILQ_REMOVE(&vsmw->segs, seg, list);
REPLACE(seg->class, NULL);
REPLACE(seg->id, NULL);
FREE_OBJ(seg);
if (fixidx) {
vsmw->nsegs--;
if (vsmw->nsubs < vsmw->nsegs || !fixidx) {
vsmw_append_record(vsmw, seg, '-');
vsmw->nsubs++;
} else {
vsmw->nsubs = 0;
vsmw_mkent(vsmw, vsmw->idx);
REPLACE(t, VSB_data(vsmw->vsb));
AN(t);
......@@ -208,8 +228,8 @@ vsmw_delseg(struct vsmw *vsmw, struct vsmwseg *seg, int fixidx)
assert(fd >= 0);
vsmw_idx_head(vsmw, fd);
VSB_clear(vsmw->vsb);
VTAILQ_FOREACH(seg, &vsmw->segs, list)
vsmw_fmt_index(vsmw, seg);
VTAILQ_FOREACH(s2, &vsmw->segs, list)
vsmw_fmt_index(vsmw, s2, '+');
AZ(VSB_finish(vsmw->vsb));
s = write(fd, VSB_data(vsmw->vsb), VSB_len(vsmw->vsb));
assert(s == VSB_len(vsmw->vsb));
......@@ -217,6 +237,9 @@ vsmw_delseg(struct vsmw *vsmw, struct vsmwseg *seg, int fixidx)
AZ(renameat(vsmw->vdirfd, t, vsmw->vdirfd, vsmw->idx));
REPLACE(t, NULL);
}
REPLACE(seg->class, NULL);
REPLACE(seg->id, NULL);
FREE_OBJ(seg);
}
/*--------------------------------------------------------------------*/
......
......@@ -463,7 +463,7 @@ vsm_vlu_plus(struct vsm *vd, struct vsm_set *vs, const char *line)
if (av[0] != NULL || ac < 4 || ac > 6) {
(void)(vsm_diag(vd,
"vsm_refresh_set2: bad index (%d/%s)",
"vsm_vlu_plus: bad index (%d/%s)",
ac, av[0]));
VAV_Free(av);
return(-1);
......@@ -496,6 +496,39 @@ vsm_vlu_plus(struct vsm *vd, struct vsm_set *vs, const char *line)
return (0);
}
static int
vsm_vlu_minus(struct vsm *vd, struct vsm_set *vs, const char *line)
{
char **av;
int ac;
struct vsm_seg *vg, *vg2;
av = VAV_Parse(line + 1, &ac, 0);
if (av[0] != NULL || ac < 4 || ac > 6) {
(void)(vsm_diag(vd,
"vsm_vlu_minus: bad index (%d/%s)",
ac, av[0]));
VAV_Free(av);
return(-1);
}
VTAILQ_FOREACH_SAFE(vg, &vs->segs, list, vg2) {
if (vsm_cmp_av(&vg->av[1], &av[1]))
continue;
VTAILQ_REMOVE(&vs->segs, vg, list);
if (vg->refs) {
vg->flags |= VSM_FLAG_STALE;
VTAILQ_INSERT_TAIL(&vs->stale, vg, list);
} else {
VAV_Free(vg->av);
FREE_OBJ(vg);
}
break;
}
return (0);
}
static int v_matchproto_(vlu_f)
vsm_vlu_func(void *priv, const char *line)
{
......@@ -519,6 +552,9 @@ vsm_vlu_func(void *priv, const char *line)
case '+':
i = vsm_vlu_plus(vd, vs, line);
break;
case '-':
i = vsm_vlu_minus(vd, vs, line);
break;
default:
break;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment