source: trunk/server/common/patches/openafs-d_splice_alias-reference.patch @ 2659

Last change on this file since 2659 was 2659, checked in by andersk, 9 years ago
OpenAFS: upgrade to 1.6.11pre1, plus patch for d_alias change
File size: 2.7 KB
RevLine 
[2659]1From b1f23baecb2de72b44cda8bba27615c012a445f1 Mon Sep 17 00:00:00 2001
[2655]2From: Marc Dionne <marc.dionne@your-file-system.com>
3Date: Thu, 18 Dec 2014 08:43:22 -0500
4Subject: [PATCH] Linux: d_splice_alias may drop inode reference on error
5
6d_splice_alias now drops the inode reference on error, so we
7need to grab an extra one to make sure that the inode doesn't
8go away, and release it when done if there was no error.
9
10For kernels that may not drop the reference, provide an
11additional iput() within an ifdef.  This could be hooked up
12to a configure option to allow building a module for a kernel
13that is known not to drop the reference on error.  That hook
14is not provided here.  Affected kernels should be the early
153.17 ones (3.17 - 3.17.2); 3.16 and older kernels should not
16return errors here.
17
18Change-Id: Id1786ac2227b4d8e0ae801fe59c15a0ecd975bed
19---
[2659]20 acinclude.m4                 |  3 +++
21 src/afs/LINUX/osi_vnodeops.c | 29 ++++++++++++++++++++++++++---
22 2 files changed, 29 insertions(+), 3 deletions(-)
[2655]23
[2659]24diff --git a/acinclude.m4 b/acinclude.m4
25index 96adde0..19f7092 100644
26--- a/acinclude.m4
27+++ b/acinclude.m4
28@@ -984,6 +984,9 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*)
29                 AC_CHECK_LINUX_FUNC([hlist_unhashed],
30                                     [#include <linux/list.h>],
31                                     [hlist_unhashed(0);])
32+                AC_CHECK_LINUX_FUNC([ihold],
33+                                    [#include <linux/fs.h>],
34+                                    [ihold(NULL);])
35                 AC_CHECK_LINUX_FUNC([i_size_read],
36                                     [#include <linux/fs.h>],
37                                     [i_size_read(NULL);])
[2655]38diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c
[2659]39index b2ab9d5..cedfef6 100644
[2655]40--- a/src/afs/LINUX/osi_vnodeops.c
41+++ b/src/afs/LINUX/osi_vnodeops.c
[2659]42@@ -1612,6 +1612,17 @@ afs_linux_lookup(struct inode *dip, struct dentry *dp)
[2655]43        ip->i_flags |= S_AUTOMOUNT;
44 #endif
45     }
46+    /*
47+     * Take an extra reference so the inode doesn't go away if
48+     * d_splice_alias drops our reference on error.
49+     */
50+    if (ip)
[2659]51+#ifdef HAVE_LINUX_IHOLD
52+       ihold(ip);
53+#else
[2655]54+       igrab(ip);
[2659]55+#endif
[2655]56+
57     newdp = d_splice_alias(ip, dp);
58 
59  done:
[2659]60@@ -1625,14 +1636,26 @@ afs_linux_lookup(struct inode *dip, struct dentry *dp)
[2655]61         * d_splice_alias can return an error (EIO) if there is an existing
62         * connected directory alias for this dentry.
63         */
64-       if (!IS_ERR(newdp))
65+       if (!IS_ERR(newdp)) {
66+           iput(ip);
67            return newdp;
68-       else {
69+       } else {
70            d_add(dp, ip);
71+           /*
72+            * Depending on the kernel version, d_splice_alias may or may
73+            * not drop the inode reference on error.  If it didn't, do it
74+            * here.
75+            */
76+#if defined(D_SPLICE_ALIAS_LEAK_ON_ERROR)
77+           iput(ip);
78+#endif
79            return NULL;
80        }
81-    } else
82+    } else {
83+       if (ip)
84+           iput(ip);
85        return ERR_PTR(afs_convert_code(code));
86+    }
87 }
88 
89 static int
90--
912.2.1
92
Note: See TracBrowser for help on using the repository browser.