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.