Re: ovl: set I_CREATING on inode being created

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Aug 22, 2018 at 10:41:21AM +0200, Miklos Szeredi wrote:
> On Fri, Aug 17, 2018 at 1:16 PM, Amir Goldstein <amir73il@xxxxxxxxx> wrote:
> > Miklos,
> >
> > I have 2 questions/comments w.r.t. commit 9475938ce8cf
> > ("ovl: set I_CREATING on inode being created") in overlayfs-next.
> >
> > 1. insert_inode_locked4() sets I_CREATING not inside
> > spinlock and your patch sets it inside spinlock.
> > technically, I guess the spinlock taken inside inode_insert5()
> > to set I_NEW and insert to hash probably provides the needed
> > barriers.
> 
> I was thinking along the same lines.  However, the spinlock is already
> in L1 cache (due to new_inode_pseudo() pulling it in) and is obviously
> uncontended, so it's basically free (at least compared to the actual
> creation of a new object, which follows).
> 
> The lock here is for documentation purposes.   Using the common
> pattern also makes possible future changes to i_state rules simpler.

IIRC from scalability stuff I did years ago, the reason the I_NEW
flag is set under the i_lock is to make the addition of the flag
atomic w.r.t. the inode hash insertion. This guarantees that by the
time anyone finds this inode in the inode hash and take the i_lock
to check i_state, they will see the I_NEW flag.

All the other initialisations that are done under the spinlock are
in places where we need to ensure that memory barriers are placed
(unlock to lock is required for a memory barrier) before 3rd parties
might have access to the inode (e.g. through new_inode()).


> > Do you think we should choose one of the practices
> > and stick with it??
> 
> The only lockless modification of i_state is insert_inode_locked4(),
> AFAICS.  I think it should either be converted to being locked or a
> comment added explaining why that is not done.

insert_inode_locked4() setting I_CREATING without locks on a newly
allocated inode that isn't in the inode hash looks to be safe - if
it gets inserted into the hash, then the i_lock is taken first, the
I_NEW flag is OR'd in and then it's inserted into the hash. Hence it
provides the same 3rd party visibility guarantees to I_CREATING as
it provides I_NEW.

> > 2. I find it nicer if ovl_new_inode() would return an I_CREATING
> > inode, to conform with the users of inode_insert_locked4() (e.g.
> > btrfs_new_inode()) this will conform with the pattern:
> > inode = XXXfs_new_inode(...);
> > d_instantiate_new(dentry, inode);
> > The call site d_make_root(ovl_new_inode(sb, S_IFDIR, 0));
> > could either use a variant of ovl_new_inode() or we could
> > let ovl_inode_init() clear I_CREATING.
> 
> Normal filesystems already know the hash key when allocating the
> in-core inode.  That's not the case for overlay, that's why we need
> the unusual sequence of calls.  Basically before the inode is inserted
> it just doesn't matter when I_CREATING is set, we could just as well
> set it right before calling inode_insert5().

Yes, that's my understanding of how it's supposed to work, too.
I_CREATING just needs to be set on the inode before it is inserted
into the hash under the i_lock.

Cheers,

Dave.
-- 
Dave Chinner
david@xxxxxxxxxxxxx



[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux