new primitive: discard_new_inode()
authorAl Viro <viro@zeniv.linux.org.uk>
Thu, 28 Jun 2018 19:53:17 +0000 (15:53 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Fri, 3 Aug 2018 19:55:30 +0000 (15:55 -0400)
commitc2b6d621c4ffe9936adf7a55c8b1c769672c306f
treed13dbb52a33dd594a78b8996132c7e7bba6f296f
parentc971e6a006175bd0f195c6346c4e8bc4089bec00
new primitive: discard_new_inode()

We don't want open-by-handle picking half-set-up in-core
struct inode from e.g. mkdir() having failed halfway through.
In other words, we don't want such inodes returned by iget_locked()
on their way to extinction.  However, we can't just have them
unhashed - otherwise open-by-handle immediately *after* that would've
ended up creating a new in-core inode over the on-disk one that
is in process of being freed right under us.

Solution: new flag (I_CREATING) set by insert_inode_locked() and
removed by unlock_new_inode() and a new primitive (discard_new_inode())
to be used by such halfway-through-setup failure exits instead of
unlock_new_inode() / iput() combinations.  That primitive unlocks new
inode, but leaves I_CREATING in place.

iget_locked() treats finding an I_CREATING inode as failure
(-ESTALE, once we sort out the error propagation).
insert_inode_locked() treats the same as instant -EBUSY.
ilookup() treats those as icache miss.

[Fix by Dan Carpenter <dan.carpenter@oracle.com> folded in]

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/dcache.c
fs/inode.c
include/linux/fs.h