gc: Made lfsr_fs_gc a bit smarter when flags change
Now we consider if it's still possible for the current traversal to make
progress. If it can, we continue with the relevant masked flags,
otherwise we restart. This should prevent us from traversing the
filesystem for no reason.
I also reverted the ckedmeta/ckeddata flags, these ended up just adding
code cost. We're not in the stack hot-path anyways...
Code changes:
code stack
before: 36244 2680
after: 36228 (-0.0%) 2680 (+0.0%)
This commit is contained in:
@@ -5924,14 +5924,6 @@ static inline bool lfsr_f_hasorphans(uint32_t flags) {
|
|||||||
return flags & LFS_F_ORPHANS;
|
return flags & LFS_F_ORPHANS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool lfsr_f_hasckedmeta(uint32_t flags) {
|
|
||||||
return flags & LFS_F_CKEDMETA;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool lfsr_f_hasckeddata(uint32_t flags) {
|
|
||||||
return flags & LFS_F_CKEDDATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
// on-demand flags
|
// on-demand flags
|
||||||
|
|
||||||
// needed in lfsr_fs_isinconsistent
|
// needed in lfsr_fs_isinconsistent
|
||||||
@@ -13040,14 +13032,6 @@ int lfsr_fs_gc(lfs_t *lfs, lfs_soff_t steps, uint32_t flags) {
|
|||||||
LFS_ASSERT(!lfsr_t_ismtreeonly(flags) || !lfsr_t_islookahead(flags));
|
LFS_ASSERT(!lfsr_t_ismtreeonly(flags) || !lfsr_t_islookahead(flags));
|
||||||
LFS_ASSERT(!lfsr_t_ismtreeonly(flags) || !lfsr_t_isckdata(flags));
|
LFS_ASSERT(!lfsr_t_ismtreeonly(flags) || !lfsr_t_isckdata(flags));
|
||||||
|
|
||||||
// do we really need a full traversal?
|
|
||||||
if (!(lfsr_t_islookahead(flags)
|
|
||||||
|| lfsr_t_iscompact(flags)
|
|
||||||
|| lfsr_t_isckmeta(flags)
|
|
||||||
|| lfsr_t_isckdata(flags))) {
|
|
||||||
flags |= LFS_T_MTREEONLY;
|
|
||||||
}
|
|
||||||
|
|
||||||
// fix pending grms if requested
|
// fix pending grms if requested
|
||||||
if (lfsr_t_ismkconsistent(flags)
|
if (lfsr_t_ismkconsistent(flags)
|
||||||
&& lfsr_grm_count(lfs) > 0) {
|
&& lfsr_grm_count(lfs) > 0) {
|
||||||
@@ -13069,42 +13053,54 @@ int lfsr_fs_gc(lfs_t *lfs, lfs_soff_t steps, uint32_t flags) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// every time we call lfsr_fs_gc with ckmeta/ckdata, assume we want
|
|
||||||
// a new traversal
|
|
||||||
lfs->flags &= ~(LFS_F_CKEDMETA | LFS_F_CKEDDATA);
|
|
||||||
|
|
||||||
// do we have any pending work?
|
// do we have any pending work?
|
||||||
while ((lfs_off_t)steps > 0
|
uint32_t pending = flags & (
|
||||||
&& ((lfsr_t_ismkconsistent(flags)
|
((lfsr_f_hasorphans(lfs->flags)) ? LFS_GC_MKCONSISTENT : 0)
|
||||||
&& lfsr_f_hasorphans(lfs->flags))
|
| ((lfsr_fs_canlookahead(lfs)) ? LFS_GC_LOOKAHEAD : 0)
|
||||||
|| (lfsr_t_islookahead(flags)
|
| ((lfsr_i_isuncompacted(lfs->flags)) ? LFS_GC_COMPACT : 0)
|
||||||
&& lfsr_fs_canlookahead(lfs))
|
| LFS_GC_CKMETA
|
||||||
|| (lfsr_t_iscompact(flags)
|
| LFS_GC_CKDATA);
|
||||||
&& lfsr_i_isuncompacted(lfs->flags))
|
|
||||||
|| (lfsr_t_isckmeta(flags)
|
while (pending && (lfs_off_t)steps > 0) {
|
||||||
&& !lfsr_f_hasckedmeta(lfs->flags))
|
|
||||||
|| (lfsr_t_isckdata(flags)
|
|
||||||
&& !lfsr_f_hasckeddata(lfs->flags)))) {
|
|
||||||
// checkpoint the allocator to maximize any lookahead scans
|
// checkpoint the allocator to maximize any lookahead scans
|
||||||
lfs_alloc_ckpoint(lfs);
|
lfs_alloc_ckpoint(lfs);
|
||||||
|
|
||||||
// start a new traversal?
|
// start a new traversal?
|
||||||
if (!lfsr_omdir_isopen(lfs, &lfs->gc.o.o)) {
|
if (!lfsr_omdir_isopen(lfs, &lfs->gc.o.o)) {
|
||||||
lfs->gc = LFSR_TRAVERSAL(flags);
|
lfs->gc = LFSR_TRAVERSAL(pending);
|
||||||
lfsr_omdir_open(lfs, &lfs->gc.o.o);
|
lfsr_omdir_open(lfs, &lfs->gc.o.o);
|
||||||
|
|
||||||
// existing traversal?
|
// existing traversal?
|
||||||
} else {
|
} else {
|
||||||
// note that we mask flags (except mtreeonly)! if you change flags
|
// mask flags, we can't trust existing traversals to make
|
||||||
// mid-traversal, the result is equivalent to the worst-case set
|
// progress if flags change
|
||||||
// of flags
|
|
||||||
lfs->gc.o.o.flags &= ~(
|
lfs->gc.o.o.flags &= ~(
|
||||||
LFS_GC_MKCONSISTENT
|
LFS_GC_MKCONSISTENT
|
||||||
| LFS_GC_LOOKAHEAD
|
| LFS_GC_LOOKAHEAD
|
||||||
| LFS_GC_COMPACT
|
| LFS_GC_COMPACT
|
||||||
| LFS_GC_CKMETA
|
| LFS_GC_CKMETA
|
||||||
| LFS_GC_CKDATA
|
| LFS_GC_CKDATA
|
||||||
) | flags;
|
) | pending;
|
||||||
|
|
||||||
|
// will this traversal still make progress? no? start over
|
||||||
|
if (!(lfs->gc.o.o.flags & (
|
||||||
|
LFS_GC_MKCONSISTENT
|
||||||
|
| LFS_GC_LOOKAHEAD
|
||||||
|
| LFS_GC_COMPACT
|
||||||
|
| LFS_GC_CKMETA
|
||||||
|
| LFS_GC_CKDATA))) {
|
||||||
|
lfsr_omdir_close(lfs, &lfs->gc.o.o);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// do we really need a full traversal?
|
||||||
|
if (!(lfs->gc.o.o.flags & (
|
||||||
|
LFS_GC_LOOKAHEAD
|
||||||
|
| LFS_GC_COMPACT
|
||||||
|
| LFS_GC_CKMETA
|
||||||
|
| LFS_GC_CKDATA))) {
|
||||||
|
lfs->gc.o.o.flags |= LFS_T_MTREEONLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// progress gc
|
// progress gc
|
||||||
@@ -13114,13 +13110,25 @@ int lfsr_fs_gc(lfs_t *lfs, lfs_soff_t steps, uint32_t flags) {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// end of traversal?
|
||||||
if (err == LFS_ERR_NOENT) {
|
if (err == LFS_ERR_NOENT) {
|
||||||
lfsr_omdir_close(lfs, &lfs->gc.o.o);
|
lfsr_omdir_close(lfs, &lfs->gc.o.o);
|
||||||
|
|
||||||
// consider our filesystem checked if we complete at least
|
// clear any pending flags we make progress on
|
||||||
// one traversal
|
pending &= ~(
|
||||||
lfs->flags |= ((lfsr_t_isckmeta(flags)) ? LFS_F_CKEDMETA : 0)
|
((!lfsr_f_hasorphans(lfs->flags))
|
||||||
| ((lfsr_t_isckdata(flags)) ? LFS_F_CKEDDATA : 0);
|
? LFS_GC_MKCONSISTENT
|
||||||
|
: 0)
|
||||||
|
| ((!lfsr_fs_canlookahead(lfs))
|
||||||
|
? LFS_GC_LOOKAHEAD
|
||||||
|
: 0)
|
||||||
|
| ((!lfsr_i_isuncompacted(lfs->flags))
|
||||||
|
? LFS_GC_COMPACT
|
||||||
|
: 0)
|
||||||
|
// consider our filesystem checked if we complete at
|
||||||
|
// least one traversal
|
||||||
|
| LFS_GC_CKMETA
|
||||||
|
| LFS_GC_CKDATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
// decrement steps
|
// decrement steps
|
||||||
|
|||||||
@@ -140,8 +140,6 @@ enum lfs_fsinfo_flags {
|
|||||||
|
|
||||||
// internally used flags
|
// internally used flags
|
||||||
LFS_F_ORPHANS = 0x8000, // Filesystem may have untracked orphans
|
LFS_F_ORPHANS = 0x8000, // Filesystem may have untracked orphans
|
||||||
LFS_F_CKEDMETA = 0x2000, // Filesystem metadata checked during gc
|
|
||||||
LFS_F_CKEDDATA = 0x4000, // Filesystem data checked during gc
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// File types
|
// File types
|
||||||
|
|||||||
Reference in New Issue
Block a user