Changes between Initial Version and Version 1 of Ticket #387, comment 3


Ignore:
Timestamp:
Nov 8, 2013, 9:36:42 AM (11 years ago)
Author:
andersk
Comment:

Legend:

Unmodified
Added
Removed
Modified
  • Ticket #387, comment 3

    initial v1  
    1 Okay, I have a promising theory, and I’m now testing the following patch on b-m, p-b, r-m, and w-e:
    2 
    3 {{{
    4 From: Anders Kaseorg <andersk@mit.edu>
    5 Date: Fri, 8 Nov 2013 08:53:59 -0500
    6 Subject: [PATCH] Linux: canonical_dentry: Don’t reverse the order if D_ALIAS_IS_HLIST
    7 
    8 It turns out commit 6bea047fb404bde828c6358ae06f7941aa2bc959 “Linux
    9 3.6: d_alias and i_dentry are now hlists” had a second bug (the first
    10 being the one fixed by commit a71cc5511c115c1b6cb4a6a2997a846bab6e19e2
    11 “Linux: osi_TryEvictVCache: Don’t skip the first dentry if
    12 D_ALIAS_IS_HLIST”).  Since there is no corresponding hlist function
    13 for list_for_each_entry_reverse, the commit just used
    14 hlist_for_each_entry.  But that changed the search order so that
    15 canonical_dentry now chose the newest dentry in the i_dentry list
    16 instead of the oldest one!
    17 
    18 Since the newest dentry may change at any time, this defeated the
    19 protections of commit dda3ea5f9ddda389955249e17a2e97b2e5ce7f1c “Linux:
    20 Make dir dentry aliases act like symlinks”.  I believe this to be the
    21 cause of the symptoms on scripts.mit.edu servers where getcwd()
    22 mysteriously starts returning ENOENT.
    23 
    24 Fix the canonical_dentry algorithm to find the oldest dentry, like it
    25 did before d_alias became an hlist, but using forward iteration
    26 instead of reverse iteration.  Clarify the variable name and comments
    27 to make clear that this is important.
    28 
    29 Change-Id: I9d31f90fd63e44dcde62d0257059c09527b4f93a
    30 Signed-off-by: Anders Kaseorg <andersk@mit.edu>
    31 ---
    32  src/afs/LINUX/osi_vnodeops.c | 15 ++++++---------
    33  1 file changed, 6 insertions(+), 9 deletions(-)
    34 
    35 diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c
    36 index 2a29625..fabf575 100644
    37 --- a/src/afs/LINUX/osi_vnodeops.c
    38 +++ b/src/afs/LINUX/osi_vnodeops.c
    39 @@ -839,14 +839,14 @@ static struct dentry *
    40  canonical_dentry(struct inode *ip)
    41  {
    42      struct vcache *vcp = VTOAFS(ip);
    43 -    struct dentry *first = NULL, *ret = NULL, *cur;
    44 +    struct dentry *oldest = NULL, *ret = NULL, *cur;
    45  #if defined(D_ALIAS_IS_HLIST) && !defined(HLIST_ITERATOR_NO_NODE)
    46      struct hlist_node *p;
    47  #endif
    48  
    49      /* general strategy:
    50       * if vcp->target_link is set, and can be found in ip->i_dentry, use that.
    51 -     * otherwise, use the first dentry in ip->i_dentry.
    52 +     * otherwise, use the oldest (tail) dentry in ip->i_dentry.
    53       * if ip->i_dentry is empty, use the 'dentry' argument we were given.
    54       */
    55      /* note that vcp->target_link specifies which dentry to use, but we have
    56 @@ -869,20 +869,17 @@ canonical_dentry(struct inode *ip)
    57      hlist_for_each_entry(cur, p, &ip->i_dentry, d_alias) {
    58  # endif
    59  #else
    60 -    list_for_each_entry_reverse(cur, &ip->i_dentry, d_alias) {
    61 +    list_for_each_entry(cur, &ip->i_dentry, d_alias) {
    62  #endif
    63  
    64         if (!vcp->target_link || cur == vcp->target_link) {
    65             ret = cur;
    66 -           break;
    67         }
    68  
    69 -       if (!first) {
    70 -           first = cur;
    71 -       }
    72 +       oldest = cur;
    73      }
    74 -    if (!ret && first) {
    75 -       ret = first;
    76 +    if (!ret && oldest) {
    77 +       ret = oldest;
    78      }
    79  
    80      vcp->target_link = ret;
    81 --
    82 1.8.5.rc0
    83 }}}
     1Okay, I have a promising theory, and I’m now testing [http://gerrit.openafs.org/10444 this patch] on b-m, p-b, r-m, and w-e.