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.