source: branches/fc19-dev/server/common/patches/openafs-TryEvictVCache-crash.patch @ 2797

Last change on this file since 2797 was 2434, checked in by achernya, 11 years ago
Merge r2402-r2433 from trunk to branches/fc19-dev
File size: 2.8 KB
  • src/afs/LINUX/osi_vcache.c

    From eafc370c0eba7949d85547ebc27574aa106d3355 Mon Sep 17 00:00:00 2001
    From: Anders Kaseorg <andersk@mit.edu>
    Date: Tue, 7 May 2013 00:27:33 -0400
    Subject: [PATCH] =?UTF-8?q?Linux:=20osi=5FTryEvictVCache:=20Don=E2=80=99t?=
     =?UTF-8?q?=20skip=20the=20first=20dentry=20if=20D=5FALIAS=5FIS=5FHLIST?=
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    An hlist doesn’t begin with a sentinel like a list does, so the old
    code would skip the first dentry or crash with a NULL dereference if
    there wasn’t one.  Use the kernel’s list_for_each_entry or
    hlist_for_each_entry macros instead of trying to do it manually.
    
    Should fix a crash observed by Alex Chernyakhovsky on kernel 3.6 and
    newer.
    
    Change-Id: I6d7bd190013a0250ca896af8d5182df55a3376b0
    Signed-off-by: Anders Kaseorg <andersk@mit.edu>
    ---
     src/afs/LINUX/osi_vcache.c | 30 +++++++++---------------------
     1 file changed, 9 insertions(+), 21 deletions(-)
    
    diff --git a/src/afs/LINUX/osi_vcache.c b/src/afs/LINUX/osi_vcache.c
    index dc3685b..99aab91 100644
    a b osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) { 
    1919
    2020    struct dentry *dentry;
    2121    struct inode *inode = AFSTOV(avc);
    22 #if defined(D_ALIAS_IS_HLIST)
    23     struct hlist_node *cur, *head, *list_end;
    24 #else
    25     struct list_head *cur, *head, *list_end;
     22#if defined(D_ALIAS_IS_HLIST) && !defined(HLIST_ITERATOR_NO_NODE)
     23    struct hlist_node *p;
    2624#endif
    2725
    2826    /* First, see if we can evict the inode from the dcache */
    osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) { 
    3331
    3432#if defined(HAVE_DCACHE_LOCK)
    3533        spin_lock(&dcache_lock);
    36         head = &inode->i_dentry;
    3734
    3835restart:
    39         cur = head;
    40         while ((cur = cur->next) != head) {
    41             dentry = list_entry(cur, struct dentry, d_alias);
    42 
     36        list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
    4337            if (d_unhashed(dentry))
    4438                continue;
    4539            dget_locked(dentry);
    restart: 
    5751        spin_unlock(&dcache_lock);
    5852#else /* HAVE_DCACHE_LOCK */
    5953        spin_lock(&inode->i_lock);
    60 #if defined(D_ALIAS_IS_HLIST)
    61         head = inode->i_dentry.first;
    62         list_end = NULL;
    63 #else
    64         head = &inode->i_dentry;
    65         list_end = head;
    66 #endif
    6754
    6855restart:
    69         cur = head;
    70         while ((cur = cur->next) != list_end) {
    7156#if defined(D_ALIAS_IS_HLIST)
    72             dentry = hlist_entry(cur, struct dentry, d_alias);
     57# if defined(HLIST_ITERATOR_NO_NODE)
     58        hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) {
     59# else
     60        hlist_for_each_entry(dentry, p, &inode->i_dentry, d_alias) {
     61# endif
    7362#else
    74             dentry = list_entry(cur, struct dentry, d_alias);
     63        list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
    7564#endif
    76 
    7765            spin_lock(&dentry->d_lock);
    7866            if (d_unhashed(dentry)) {
    7967                spin_unlock(&dentry->d_lock);
Note: See TracBrowser for help on using the repository browser.