Re: dcache: abstract take_name_snapshot() interface

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Jan 14, 2020 at 6:22 PM Al Viro <viro@xxxxxxxxxxxxxxxxxx> wrote:
>
> On Tue, Jan 14, 2020 at 05:40:34PM +0200, Amir Goldstein wrote:
> > Generalize the take_name_snapshot()/release_name_snapshot() interface
> > so it is possible to snapshot either a dentry d_name or its snapshot.
> >
> > The order of fields d_name and d_inode in struct dentry is swapped
> > so d_name is adjacent to d_iname.  This does not change struct size
> > nor cache lines alignment.
> >
> > Currently, we snapshot the old name in vfs_rename() and we snapshot the
> > snapshot the dentry name in __fsnotify_parent() and then we pass qstr
> > to inotify which allocated a variable length event struct and copied the
> > name.
> >
> > This new interface allows us to snapshot the name directly into an
> > fanotify event struct instead of allocating a variable length struct
> > and copying the name to it.
>
> Ugh...  That looks like being too damn cute for no good reason.  That
> trick with union is _probably_ safe, but I wouldn't bet a dime on
> e.g. randomize_layout crap not screwing it over in random subset of
> gcc versions.  You are relying upon fairly subtle reading of 6.2.7
> and it feels like just the place for layout-mangling plugins to fuck
> up.
>
> With -fplan9-extensions we could go for renaming struct name_snapshot
> fields and using an anon member in struct dentry -
>         ...
>         struct inode *d_inode;
>         struct name_snapshot;   // d_name and d_iname
>         struct lockref d_lockref;
>         ...
>
> but IMO it's much safer to have an explicit
>
> // NOTE: release_dentry_name_snapshot() will be needed for both copies.
> clone_name_snapshot(struct name_snapshot *to, const struct name_snapshot *from)
> {
>         to->name = from->name;
>         if (likely(to->name.name == from->inline_name)) {
>                 memcpy(to->inline_name, from->inline_name,
>                         to->name.len);
>                 to->name.name = to->inline_name;
>         } else {
>                 struct external_name *p;
>                 p = container_of(to->name.name, struct external_name, name[0]);
>                 atomic_inc(&p->u.count);
>         }
> }
>
> and be done with that.  Avoids any extensions or tree-wide renamings, etc.

I started with something like this but than in one of the early
revisions I needed
to pass some abstract reference around before cloning the name into the event,
but with my current patches I can get away with a simple:

if (data_type == FANOTIFY_EVENT_NAME)
    clone_name_snapshot(&event->name, data);
else if (dentry)
    take_dentry_name_snapshot(&event->name, dentry);

So that simple interface should be good enough for my needs.

Thanks,
Amir.



[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux