On Fri, Nov 15, 2019 at 03:20:11PM +0800, Greg KH wrote: > > FWIW, I'm not sure it's a good solution. What are the rules for callers > > of that thing, anyway? If it can be called when somebody is creating > > more files in that subtree, we almost certainly will have massive > > problems with the lifetimes of underlying objects... > > > > Could somebody familiar with debugfs explain how is that thing actually > > used and what is required from/promised to its callers? I can try and > > grep through the tree and guess what the rules are, but I've way too > > much on my platter right now and I don't want to get sidetracked into yet > > another tree-wide search and analysis session ;-/ > > Yu wants to use simple_empty() in debugfs_remove_recursive() instead of > manually checking: > if (!list_empty(&child->d_subdirs)) { > > See patch 3 of this series for that change and why they feel it is > needed: > https://lore.kernel.org/lkml/1573788472-87426-4-git-send-email-yukuai3@xxxxxxxxxx/ > > As to if patch 3 really is needed, I'll leave that up to Yu given that I > thought we had resolved these types of issues already a year or so ago. What I'm asking is what concurrency warranties does the whole thing (debugfs_remove_recursive()) have to deal with. IMO the overall structure of the walk-and-remove the tree algorithm in there is Not Nice(tm) and I'd like to understand if it needs to be kept that way. And the locking is confused in there - it either locks too much, or not enough. So... can debugfs_remove_recursive() rely upon the lack of attempts to create new entries inside the subtree it's trying to kill? If it can, the things can be made simpler; if it can't, it's not locking enough; e.g. results of simple_empty() on child won't be guaranteed to remain unchanged just as it returns to caller. What's more, the uses of simple_unlink()/simple_rmdir() there are not imitiating the normal locking environment for ->unlink() and ->rmdir() resp. - the victim's inode is not locked, so just for starters the call of simple_empty() from simple_rmdir() itself is not guaranteed to give valid result. I want to understand the overall situation. No argument, list_empty() in there is BS, for many reasons. But I wonder if trying to keep the current structure of the iterator _and_ the use of simple_rmdir()/simple_unlink() is the right approach.