source:
trunk/server/common/patches/openafs-TryEvictVCache-crash.patch
@
2545
Last change on this file since 2545 was 2414, checked in by achernya, 12 years ago | |
---|---|
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) { 19 19 20 20 struct dentry *dentry; 21 21 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; 26 24 #endif 27 25 28 26 /* First, see if we can evict the inode from the dcache */ … … osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) { 33 31 34 32 #if defined(HAVE_DCACHE_LOCK) 35 33 spin_lock(&dcache_lock); 36 head = &inode->i_dentry;37 34 38 35 restart: 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) { 43 37 if (d_unhashed(dentry)) 44 38 continue; 45 39 dget_locked(dentry); … … restart: 57 51 spin_unlock(&dcache_lock); 58 52 #else /* HAVE_DCACHE_LOCK */ 59 53 spin_lock(&inode->i_lock); 60 #if defined(D_ALIAS_IS_HLIST)61 head = inode->i_dentry.first;62 list_end = NULL;63 #else64 head = &inode->i_dentry;65 list_end = head;66 #endif67 54 68 55 restart: 69 cur = head;70 while ((cur = cur->next) != list_end) {71 56 #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 73 62 #else 74 dentry = list_entry(cur, struct dentry, d_alias);63 list_for_each_entry(dentry, &inode->i_dentry, d_alias) { 75 64 #endif 76 77 65 spin_lock(&dentry->d_lock); 78 66 if (d_unhashed(dentry)) { 79 67 spin_unlock(&dentry->d_lock);
Note: See TracBrowser
for help on using the repository browser.