Re: [PATCH 11/11] ovl: Put barriers to order oi->__upperdentry and OVL_METACOPY update

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

 



On Thu, Oct 19, 2017 at 4:00 PM, Vivek Goyal <vgoyal@xxxxxxxxxx> wrote:
> On Wed, Oct 18, 2017 at 08:40:59AM +0300, Amir Goldstein wrote:
>> On Wed, Oct 18, 2017 at 12:05 AM, Vivek Goyal <vgoyal@xxxxxxxxxx> wrote:
>> > OVL_METACOPY in oi->flags can be accessed in lockless manner. So if a file
>> > is being copied up metadata only, we need to make sure that upperdentry is
>> > visible only after OVL_METACOPY flag has been set. IOW, if oi->__upperdentry
>> > is visble to a cpu, then we also need to make sure any updates to OVL_METACOPY
>> > flags are visible too.
>> >
>>
>> You know, I have a feeling that this ordering requirement could be simplified or
>> completely avoided if you flip the meaning of the flag, i.e.:
>>
>> bool ovl_dentry_has_upper_data(struct dentry *dentry)
>> {
>>         return ovl_test_flag(OVL_UPPER_DATA, d_inode(dentry));
>> }
>>
>> Then flag visibility requirements are the same as visibility requirements
>> for oe->has_upper.
>> You probably don't need to add any new barriers for setting setting the flag
>> on normal copy up.
>> For setting the flag in copy_up_meta_inode_data, and testing the flag
>> in ovl_d_real() the requirements stay the same as you implemented in patch 10.
>
> Hi Amir,
>
> I thought about it and IIUC, flipping the bit does not do away with the
> ordering requirement w.r.t ovl_inode_update(). For example.
>
> Say on CPU1 a file is being copied up (both data and metadata copy up).
>
> ovl_copy_up_inode()
> install inode;
> ovl_set_flag(OVL_UPPER_DATA);
> ovl_inode_update();
>
> Assume, Say another CPU2 is doing d_real() with flags=0.
>
> ovl_d_real()
>   real = ovl_dentry_upper(dentry);
>   if (real) {
>         if (!ovl_test_flag(OVL_UPPER_DATA, d_inode(dentry)))
>                 goto lower;
>   }
>
> Now assume that CPU2 has not seen the update of OVL_UPPER_DATA yet. So it
> will end up returning a "lower" dentry, while it should have returned
> an upper dentry. So ordering requirement is very much still there.
>
> What do you think?

Process 2 will get lower dentry on open for read at 8AM
Process 1 will copy up file at 9AM (on CPU1)
Process 2 will open same file for read at 9AM (on CPU2)
Does it matter if process 2 gets lower or upper dentry? No.
It only matter that IF process 2 gets an upper dentry, that
this dentry is consistent, so it only matters that IF __upperdentry
is visible to CPU2 AND OVL_UPPER_DATA flag is visible to
CPU2 then dentry and its inode are consistent.

So IMO you may only need to add smp_rmb() before
ovl_test_flag(OVL_UPPER_DATA in ovl_d_real() and the smp_wmb()
in ovl_inode_update() should be sufficient.
Change the comment in ovl_inode_update() to mention that wmb also
matches rmb in ovl_d_real() w.r.t OVL_UPPER_DATA flag.


>
> To simplify ordering requirements w.r.t ovl_inode_updat(), can we replace
> data dependency barrier in ovl_upperdentry_dereference() with a read
> barrier instead (smp_rmb()). That way we will not have to introduce
> this additional smp_rmb() everything and code will be simpler.
>
> Thoughts?
>

I am am right with my claims above, this can be avoided.

Amir.
--
To unsubscribe from this list: send the line "unsubscribe linux-unionfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Filesystems Devel]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux