On Sat, Sep 14, 2019 at 10:15:22AM -0700, Linus Torvalds wrote: > On Sat, Sep 14, 2019 at 10:01 AM Al Viro <viro@xxxxxxxxxxxxxxxxxx> wrote: > > > > I thought of that, but AFAICS rename(2) is a fatal problem for such > > a scheme. > > Duh. You're obviously correct, and I didn't think it through. Getting the cursors out of the list is obviously tempting; if we could make simple_rename() take care of those it might be worth doing. I played with having them hashed by middle bits of target dentry address (we have enough fields unused for cursor dentries), but the problem is that we'd need to scan the full hash chain on simple_rename() for that to work. Or keep the chains ordered, but that's even more painful - moving cursors would become costly. That approach needs something to represent the following data and primitives: non-intersecting sets Cursors(dentry) (empty for most of dentries) by given cursor find dentry such that cursor \in Cursors(dentry) remove given cursor from the set it belongs to add given cursor to Cursors(dentry) move everything from Cursors(dentry1) into Cursors(dentry2) An obvious approach would be to have them sit in the lists hanging off dentries, with pointer to dentry in the cursor itself. It's not hard to do, with "move" costing O(#Cursors(dentry1)) and everything else being O(1), but I hate adding a pointer to each struct dentry, when it's completely useless for most of the filesystems *and* NULL for most of dentries on dcache_readdir()-using one. We could try to be smart with ->d_fsdata, but at least autofs and debugfs are already using that ;-/ Hell knows - in any case, that's far too intrusive by that point in the cycle, so I decided to leave any work in that direction for later. I might be missing something obvious, though, so any suggestions would be welcome.