Re: d_genocide()? What about d_holodomor(), d_massmurder(), d_execute_warcrimes()? Re: [PATCH 15/20] d_genocide(): move the extern into fs/internal.h

From: Al Viro
Date: Fri Nov 24 2023 - 02:49:04 EST


On Fri, Nov 24, 2023 at 06:57:59AM +0000, Al Viro wrote:
> > > +extern void d_genocide(struct dentry *);
> >
> > Seriously, who came up with THAT name? "Genocide" is not a nice term,
> > not even if you ignore political correctness.
> > Or what will be next? d_holodomor()? d_massmurder()? d_execute_warcrimes()?
>
> kill_them_all(), on the account of that being what it's doing?

To elaborate a bit: what that function does (well, tries to do - it has
serious limitations, which is why there is only one caller remaining and
that one is used only when nothing else can access the filesystem anymore)
is "kill given dentry, along with all its children, all their children,
etc."

I sincerely doubt that you will be able to come up with _any_ word
describing such action in any real-world context that would not come
with very nasty associations.

Context: a bunch of filesystems have directory tree entirely in dcache;
creating a file or directory bumps the reference count of dentry in
question, so instead of going back to 0 after e.g. mkdir(2) returns
it is left with refcount 1, which prevents its eviction. In effect,
all positive dentries in there are artificially kept busy. On
rmdir(2) or unlink(2) that extra reference is dropped and they
get evicted.

For filesystems like e.g. tmpfs that's a fairly obvious approach -
they don't *have* any backing store, so dcache is not just caching
the underlying objects - it's all there is.

For such filesystems there is a quick way to do an equivalent of
rm -rf - simply go over the subtree you want to remove and decrement
refcounts of everything positive. That's fine on filesystem shutdown,
but for anything in use it is *too* quick - you'd better not do that
if there are mountpoints in the subtree you are removing, etc.

At the moment we have 3 callers in the kernel; one in selinuxfs, removing
stale directories on policy reload (not quite safe, but if attacker can
do selinux policy reload, you are beyond lost), another in
simple_fill_super() failure handling (safe, since filesystem is not
mounted at the time, but actually pointless - normal cleanup after
failure will take them out just fine) and the last one in
kill_litter_super(). That one is actually fine - we are shutting the
filesystem down and nobody can access it at that point unless the
kernel is deeply broken.

By the end of this series only that one caller remains, which is
reason for taking the declaration from include/linux/dcache.h to
fs/internal.h - making sure no new callers get added. Not because
of the identifier having nasty connotations, but because it's
pretty hard to use correctly.