Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1620943 > unrolled thread

Re: [git pull] vfs fixes

Started byLinus Torvalds <torvalds@linux-foundation.org>
First post2017-04-11 08:20 +0200
Last post2017-04-12 09:10 +0200
Articles 4 — 3 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: [git pull] vfs fixes Linus Torvalds <torvalds@linux-foundation.org> - 2017-04-11 08:20 +0200
    Re: [git pull] vfs fixes Al Viro <viro@ZenIV.linux.org.uk> - 2017-04-11 08:50 +0200
      Re: [git pull] vfs fixes Andreas Dilger <adilger@dilger.ca> - 2017-04-11 23:10 +0200
        Re: [git pull] vfs fixes Linus Torvalds <torvalds@linux-foundation.org> - 2017-04-12 09:10 +0200

#1620943 — Re: [git pull] vfs fixes

FromLinus Torvalds <torvalds@linux-foundation.org>
Date2017-04-11 08:20 +0200
SubjectRe: [git pull] vfs fixes
Message-ID<tuXjI-3jn-19@gated-at.bofh.it>
Hey Al,
 mind looking at fs/namei,c line 2186:

                if (likely(!nd_jump_root(nd)))
                        return s;
                nd->root.mnt = NULL;
-->             rcu_read_unlock();   <--
                return ERR_PTR(-ECHILD);

because that rcu_read_unlock() looks odd.

It looks odd because the lock part is

                if (flags & LOOKUP_RCU)
                        rcu_read_lock();

ie it's locked conditionally, and the code in between does not seem to
return every time LOOKUP_RCU is clear.

So mind giving this a look? Is it as obviously buggy as I think it is,
or is there something I'm missing?

              Linus

[toc] | [next] | [standalone]


#1620954

FromAl Viro <viro@ZenIV.linux.org.uk>
Date2017-04-11 08:50 +0200
Message-ID<tuXMJ-3sI-11@gated-at.bofh.it>
In reply to#1620943
On Mon, Apr 10, 2017 at 11:10:19PM -0700, Linus Torvalds wrote:

> It looks odd because the lock part is
> 
>                 if (flags & LOOKUP_RCU)
>                         rcu_read_lock();
> 
> ie it's locked conditionally, and the code in between does not seem to
> return every time LOOKUP_RCU is clear.
> 
> So mind giving this a look? Is it as obviously buggy as I think it is,
> or is there something I'm missing?

It's more obscure than I would like, and can grow into a bug one day, but...
nd_jump_root() can only return non-zero if you have LOOKUP_RCU.  So without
LOOKUP_RCU in flags, this
                if (flags & LOOKUP_RCU)
                        rcu_read_lock();
                set_root(nd);
                if (likely(!nd_jump_root(nd)))
                        return s;
                nd->root.mnt = NULL;
                rcu_read_unlock();
won't get to that rcu_read_unlock() at all - it'll get zero from nd_jump_root()
and proceed to return s;

[toc] | [prev] | [next] | [standalone]


#1621620

FromAndreas Dilger <adilger@dilger.ca>
Date2017-04-11 23:10 +0200
Message-ID<tvbd0-3RY-5@gated-at.bofh.it>
In reply to#1620954

[Multipart message — attachments visible in raw view] — view raw

On Apr 11, 2017, at 12:48 AM, Al Viro <viro@ZenIV.linux.org.uk> wrote:
> On Mon, Apr 10, 2017 at 11:10:19PM -0700, Linus Torvalds wrote:
> 
>> It looks odd because the lock part is
>> 
>>                if (flags & LOOKUP_RCU)
>>                        rcu_read_lock();
>> 
>> ie it's locked conditionally, and the code in between does not seem to
>> return every time LOOKUP_RCU is clear.
>> 
>> So mind giving this a look? Is it as obviously buggy as I think it is,
>> or is there something I'm missing?
> 
> It's more obscure than I would like, and can grow into a bug one day, but...
> nd_jump_root() can only return non-zero if you have LOOKUP_RCU.  So without
> LOOKUP_RCU in flags, this
>                if (flags & LOOKUP_RCU)
>                        rcu_read_lock();
>                set_root(nd);
>                if (likely(!nd_jump_root(nd)))
>                        return s;
>                nd->root.mnt = NULL;
>                rcu_read_unlock();
> won't get to that rcu_read_unlock() at all - it'll get zero from nd_jump_root()
> and proceed to return s;

So possibly a comment like the following would be helpful:

		rcu_read_unlock(); /* nd_jump_root() returns if !LOOKUP_RCU */

so that us mere mortals have a chance to understand this in the future?

Cheers, Andreas





[toc] | [prev] | [next] | [standalone]


#1621858

FromLinus Torvalds <torvalds@linux-foundation.org>
Date2017-04-12 09:10 +0200
Message-ID<tvkzD-1we-1@gated-at.bofh.it>
In reply to#1621620
On Tue, Apr 11, 2017 at 2:02 PM, Andreas Dilger <adilger@dilger.ca> wrote:
> On Apr 11, 2017, at 12:48 AM, Al Viro <viro@ZenIV.linux.org.uk> wrote:
>>
>> It's more obscure than I would like, and can grow into a bug one day, but...
>> nd_jump_root() can only return non-zero if you have LOOKUP_RCU.
>
> So possibly a comment like the following would be helpful:
>
>                 rcu_read_unlock(); /* nd_jump_root() returns if !LOOKUP_RCU */
>
> so that us mere mortals have a chance to understand this in the future?

That might be good, but the reason I noticed this at all was that I
looked at all those "if (LOOKUP_RCU)" in that function, and was
thinking that the whole function would be better being split up into
the RCU case and the non-RCU case. Because the two cases do have
shared code, but the sharing is almost less than the non-shared stuff.

And when I started doing that split to see what it looked like, that
rcu_read_unlock() really stood out like a sore thumb.

               Linus

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web