From 70bb6f65d536611b2579cfbb034805d6a393126d Mon Sep 17 00:00:00 2001 From: Benjamin Kaduk Date: Tue, 3 Feb 2015 20:54:28 -0500 Subject: [PATCH] Import a big pile of upstream patches Bring in support for new linux versions, through 3.19 hopefully. Also avoid spurious failures of getcwd() in some situations, improve the configure test for key_type.match (which caused a nasty bug on certain CentOS versions), bring in a patch that avoids file corruption in certain cases when writing large files fast enough to surpass the max dirty ratio, and fix a refcount leak that manifested as odd OOPSes. --- debian/changelog | 10 + ...x-3.17-No-more-typedef-for-ctl_table.patch | 65 +++++ ...3.17-Deal-with-d_splice_alias-errors.patch | 59 ++++ ...ck-afs_lookup-return-code-explicitly.patch | 67 +++++ ..._revalidate-failure-on-mtpt-mismatch.patch | 101 +++++++ ...alidate-can-no-longer-return-an-erro.patch | 102 +++++++ ...18-key_type-no-longer-has-a-match-op.patch | 72 +++++ ...d-check-for-key_type.match-existence.patch | 97 +++++++ ...ing-stale-DV-in-afs_StoreAllSegments.patch | 74 +++++ ...012-afs-Fix-some-afs_conn-overcounts.patch | 84 ++++++ ...-code-to-reset-the-root-to-afs-LINUX.patch | 257 ++++++++++++++++++ ...14-Linux-d_alias-becomes-d_u.d_alias.patch | 89 ++++++ .../0015-Linux-3.19-No-more-f_dentry.patch | 61 +++++ ...x-3.19-Use-mgs_iter-in-struct-msghdr.patch | 54 ++++ ...3.19-struct-nameidata-becomes-opaque.patch | 84 ++++++ ...lias-may-drop-inode-reference-on-err.patch | 138 ++++++++++ debian/patches/series | 15 + 17 files changed, 1429 insertions(+) create mode 100644 debian/patches/0004-Linux-3.17-No-more-typedef-for-ctl_table.patch create mode 100644 debian/patches/0005-Linux-3.17-Deal-with-d_splice_alias-errors.patch create mode 100644 debian/patches/0006-LINUX-Check-afs_lookup-return-code-explicitly.patch create mode 100644 debian/patches/0007-LINUX-Avoid-d_revalidate-failure-on-mtpt-mismatch.patch create mode 100644 debian/patches/0008-Linux-3.18-d_invalidate-can-no-longer-return-an-erro.patch create mode 100644 debian/patches/0009-Linux-3.18-key_type-no-longer-has-a-match-op.patch create mode 100644 debian/patches/0010-LINUX-Avoid-check-for-key_type.match-existence.patch create mode 100644 debian/patches/0011-Unix-CM-Avoid-using-stale-DV-in-afs_StoreAllSegments.patch create mode 100644 debian/patches/0012-afs-Fix-some-afs_conn-overcounts.patch create mode 100644 debian/patches/0013-Linux-Move-code-to-reset-the-root-to-afs-LINUX.patch create mode 100644 debian/patches/0014-Linux-d_alias-becomes-d_u.d_alias.patch create mode 100644 debian/patches/0015-Linux-3.19-No-more-f_dentry.patch create mode 100644 debian/patches/0016-Linux-3.19-Use-mgs_iter-in-struct-msghdr.patch create mode 100644 debian/patches/0017-Linux-3.19-struct-nameidata-becomes-opaque.patch create mode 100644 debian/patches/0018-Linux-d_splice_alias-may-drop-inode-reference-on-err.patch diff --git a/debian/changelog b/debian/changelog index e5f8b02c0..5aa02e8df 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,6 +2,16 @@ openafs (1.6.10-4) UNRELEASED; urgency=medium * Update Spanish translation, thanks Javier Fernandez-Sanguino Pena. (Closes: #773565) + * Import many patches from upstream: + - Support newer linux versions, up through 3.19. (Closes: #771298) + - Avoid some spurious getcwd() failures. + - Improve configure test for key_type.match (which caused buggy + behavior in certain versions of RHEL). + - Fix a refcount leak that would manifest as an unrelated OOPS. + - Avoid using a stale data version in certain cases when writing + files larger than the AFS cache, which manifested as file corruption. + This leaves us roughly equivalent to the forthcoming 1.6.11pre2 + release candidate. -- Benjamin Kaduk Wed, 07 Jan 2015 13:50:56 -0500 diff --git a/debian/patches/0004-Linux-3.17-No-more-typedef-for-ctl_table.patch b/debian/patches/0004-Linux-3.17-No-more-typedef-for-ctl_table.patch new file mode 100644 index 000000000..f2d942ed9 --- /dev/null +++ b/debian/patches/0004-Linux-3.17-No-more-typedef-for-ctl_table.patch @@ -0,0 +1,65 @@ +From: Marc Dionne +Date: Tue, 9 Sep 2014 10:39:55 -0300 +Subject: Linux 3.17: No more typedef for ctl_table + +The typedef has been removed so we need to use the structure +directly. + +Note that the API for register_sysctl_table has also changed +with 3.17, but it reverted back to a form that existed +before and the configure tests handle it correctly. + +Reviewed-on: http://gerrit.openafs.org/11455 +Reviewed-by: Benjamin Kaduk +Tested-by: BuildBot +Reviewed-by: Perry Ruiter +Reviewed-by: Andrew Deason +Reviewed-by: D Brashear +(cherry picked from commit 6a23ca5b6e8bcaf881be7a4c50bfba72d001e6cd) + +Change-Id: Ifb8fc0b9b01d2578c65407608f0e1b3f3b254459 +Reviewed-on: http://gerrit.openafs.org/11549 +Tested-by: BuildBot +Reviewed-by: Benjamin Kaduk +Reviewed-by: Stephan Wiesand +(cherry picked from commit 75f36df74bb3c13aadb047163b93d6c24436f784) +--- + src/afs/LINUX/osi_sysctl.c | 4 ++-- + src/cf/linux-test4.m4 | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/afs/LINUX/osi_sysctl.c b/src/afs/LINUX/osi_sysctl.c +index a8f7fac..834e8ad 100644 +--- a/src/afs/LINUX/osi_sysctl.c ++++ b/src/afs/LINUX/osi_sysctl.c +@@ -34,7 +34,7 @@ extern afs_int32 afs_pct2; + #ifdef CONFIG_SYSCTL + static struct ctl_table_header *afs_sysctl = NULL; + +-static ctl_table afs_sysctl_table[] = { ++static struct ctl_table afs_sysctl_table[] = { + { + #if defined(STRUCT_CTL_TABLE_HAS_CTL_NAME) + #if defined(CTL_UNNUMBERED) +@@ -234,7 +234,7 @@ static ctl_table afs_sysctl_table[] = { + {0} + }; + +-static ctl_table fs_sysctl_table[] = { ++static struct ctl_table fs_sysctl_table[] = { + { + #if defined(STRUCT_CTL_TABLE_HAS_CTL_NAME) + #if defined(CTL_UNNUMBERED) +diff --git a/src/cf/linux-test4.m4 b/src/cf/linux-test4.m4 +index b068af5..1759d9e 100644 +--- a/src/cf/linux-test4.m4 ++++ b/src/cf/linux-test4.m4 +@@ -395,7 +395,7 @@ AC_DEFUN([LINUX_REGISTER_SYSCTL_TABLE_NOFLAG], [ + AC_CHECK_LINUX_BUILD([whether register_sysctl_table has an insert_at_head argument], + [ac_cv_linux_register_sysctl_table_noflag], + [#include ], +- [ctl_table *t; register_sysctl_table (t);], ++ [struct ctl_table *t; register_sysctl_table (t);], + [REGISTER_SYSCTL_TABLE_NOFLAG], + [define if register_sysctl_table has no insert_at head flag], + []) diff --git a/debian/patches/0005-Linux-3.17-Deal-with-d_splice_alias-errors.patch b/debian/patches/0005-Linux-3.17-Deal-with-d_splice_alias-errors.patch new file mode 100644 index 000000000..a8f907516 --- /dev/null +++ b/debian/patches/0005-Linux-3.17-Deal-with-d_splice_alias-errors.patch @@ -0,0 +1,59 @@ +From: Marc Dionne +Date: Thu, 25 Sep 2014 07:52:12 -0300 +Subject: Linux 3.17: Deal with d_splice_alias errors + +In 3.17 the logic in d_splice_alias has changed. Of interest to +us is the fact that it will now return an EIO error if it finds +an existing connected directory for the dentry, where it would +previously have added a new alias for it. As a result the end +user can get EIO errors when accessing any file in a volume +if the volume was first accessed through a different path (ex: +RO path vs RW path). + +This commit just restores the old behaviour, adding the directory +alias manually in the error case, which is what older versions +of d_splice_alias used to do. + +Reviewed-on: http://gerrit.openafs.org/11492 +Tested-by: BuildBot +Reviewed-by: Perry Ruiter +Reviewed-by: Andrew Deason +Reviewed-by: D Brashear +(cherry picked from commit 5815ee92a41cdcf105741d834042a5617dc4c219) + +Change-Id: Ie86009ede93255c85fcf640af14c598fe1e42ca9 +Reviewed-on: http://gerrit.openafs.org/11550 +Tested-by: BuildBot +Reviewed-by: Benjamin Kaduk +Reviewed-by: Stephan Wiesand +(cherry picked from commit 663bdfcb16ab742ef12acca110f279b749f15586) +--- + src/afs/LINUX/osi_vnodeops.c | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c +index 7e5cdd1..3ddcf42 100644 +--- a/src/afs/LINUX/osi_vnodeops.c ++++ b/src/afs/LINUX/osi_vnodeops.c +@@ -1529,9 +1529,18 @@ afs_linux_lookup(struct inode *dip, struct dentry *dp) + /* It's ok for the file to not be found. That's noted by the caller by + * seeing that the dp->d_inode field is NULL. + */ +- if (!code || code == ENOENT) +- return newdp; +- else ++ if (!code || code == ENOENT) { ++ /* ++ * d_splice_alias can return an error (EIO) if there is an existing ++ * connected directory alias for this dentry. ++ */ ++ if (!IS_ERR(newdp)) ++ return newdp; ++ else { ++ d_add(dp, ip); ++ return NULL; ++ } ++ } else + return ERR_PTR(afs_convert_code(code)); + } + diff --git a/debian/patches/0006-LINUX-Check-afs_lookup-return-code-explicitly.patch b/debian/patches/0006-LINUX-Check-afs_lookup-return-code-explicitly.patch new file mode 100644 index 000000000..0591e948c --- /dev/null +++ b/debian/patches/0006-LINUX-Check-afs_lookup-return-code-explicitly.patch @@ -0,0 +1,67 @@ +From: Andrew Deason +Date: Thu, 24 Jul 2014 11:07:45 -0500 +Subject: LINUX: Check afs_lookup return code explicitly + +Checking if the returned vcache is NULL or not is a bit of an indirect +way to check if an error occurred. Just check the return code itself, +to make sure we notice if any kind of error is reported. + +Suggested by Chas Williams. + +Reviewed-on: http://gerrit.openafs.org/11321 +Reviewed-by: Chas Williams - CONTRACTOR +Tested-by: BuildBot +Reviewed-by: D Brashear +(cherry picked from commit 2edf5c0382385f898a017fd8e0e2429f8b2b3520) + +Change-Id: I7e123ab1cf88570a6b18e438e01409ed7804e014 +Reviewed-on: http://gerrit.openafs.org/11558 +Reviewed-by: Benjamin Kaduk +Tested-by: BuildBot +Reviewed-by: Stephan Wiesand +(cherry picked from commit d3f0c37b796b02e05baf9d8270bd95d713d08b62) +--- + src/afs/LINUX/osi_vnodeops.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c +index 3ddcf42..4d29efb 100644 +--- a/src/afs/LINUX/osi_vnodeops.c ++++ b/src/afs/LINUX/osi_vnodeops.c +@@ -943,6 +943,7 @@ check_bad_parent(struct dentry *dp) + cred_t *credp; + struct dentry *parent; + struct vcache *vcp, *pvc, *avc = NULL; ++ int code; + + vcp = VTOAFS(dp->d_inode); + parent = dget_parent(dp); +@@ -952,8 +953,8 @@ check_bad_parent(struct dentry *dp) + credp = crref(); + + /* force a lookup, so vcp->mvid is fixed up */ +- afs_lookup(pvc, (char *)dp->d_name.name, &avc, credp); +- if (!avc || vcp != avc) { /* bad, very bad.. */ ++ code = afs_lookup(pvc, (char *)dp->d_name.name, &avc, credp); ++ if (code || vcp != avc) { /* bad, very bad.. */ + afs_Trace4(afs_iclSetp, CM_TRACE_TMP_1S3L, ICL_TYPE_STRING, + "check_bad_parent: bad pointer returned from afs_lookup origvc newvc dentry", + ICL_TYPE_POINTER, vcp, ICL_TYPE_POINTER, avc, +@@ -1233,7 +1234,7 @@ afs_linux_dentry_revalidate(struct dentry *dp, int flags) + + credp = crref(); + code = afs_lookup(pvcp, (char *)dp->d_name.name, &tvc, credp); +- if (!tvc || tvc != vcp) { ++ if (code || tvc != vcp) { + dput(parent); + /* Force unhash; the name doesn't point to this file + * anymore. */ +@@ -1478,7 +1479,7 @@ afs_linux_lookup(struct inode *dip, struct dentry *dp) + AFS_GLOCK(); + code = afs_lookup(VTOAFS(dip), (char *)comp, &vcp, credp); + +- if (vcp) { ++ if (!code) { + struct vattr *vattr = NULL; + struct vcache *parent_vc = VTOAFS(dip); + diff --git a/debian/patches/0007-LINUX-Avoid-d_revalidate-failure-on-mtpt-mismatch.patch b/debian/patches/0007-LINUX-Avoid-d_revalidate-failure-on-mtpt-mismatch.patch new file mode 100644 index 000000000..8c1fa75ea --- /dev/null +++ b/debian/patches/0007-LINUX-Avoid-d_revalidate-failure-on-mtpt-mismatch.patch @@ -0,0 +1,101 @@ +From: Andrew Deason +Date: Tue, 28 Oct 2014 00:10:56 -0500 +Subject: LINUX: Avoid d_revalidate failure on mtpt mismatch + +Currently, if afs_linux_dentry_revalidate is given an inode that +corresponds to a mtpt vcache ('vcp'), it resolves the mtpt to its root +dir if it's easy to do so (mvid and CMValid are set). Later on, we run +afs_lookup to see if looking up our dentry's name returns the same +vcache that we got; afs_lookup presumably will also resolve the mtpt +if it's easy to do so. + +However, it is possible that afs_linux_dentry_revalidate and +afs_lookup will make different decisions as to whether or not they +resolve a mtpt to a dir. Specifically, if CMValid is cleared after +afs_linux_dentry_revalidate checks for it, but before afs_lookup does, +then afs_lookup will return a different vcache than +afs_linux_dentry_revalidate is expecting, even though the relevant +directory entry has not changed. That is, tvc is not equal to vcp, but +tvc could be a mtpt that resolves to vcp, or vice versa. CMValid can +be cleared by another thread at virtually any time, since this is +cleared in some situations when we're not sure if the mtpt resolution +is still valid (callbacks are broken, vldb cache entries expire, etc). + +afs_linux_dentry_revalidate interprets this situation to mean that the +directory entry has changed, and so it eventually d_drop's the +associated dentry. The way that this manifests to users is that a +"fakestatted" mtpt can appear to be deleted effectively randomly, even +when nothing has changed. This can be a problem because this causes +the getcwd() syscall to return ENOENT when the working directory +involves such an affected directory. + +To fix this situation, we just detect if afs_lookup returned either +'vcp' (our possibly-resolved vcache), or the original inode associated +with the dentry we are revalidating. If the returned vcache matches +either of these, then the entry is okay and we don't need to +invalidate or drop anything. + +FIXES 131780 + +Reviewed-on: http://gerrit.openafs.org/11559 +Tested-by: BuildBot +Reviewed-by: Benjamin Kaduk +Tested-by: Anders Kaseorg +Reviewed-by: Anders Kaseorg +Reviewed-by: D Brashear +(cherry picked from commit ba1cc838ab4a80b7a7787c441a79aca31d84808c) + +Change-Id: I3273cc15ebe7fd94f3127840fdc5316bd7458e7c +Reviewed-on: http://gerrit.openafs.org/11568 +Reviewed-by: Anders Kaseorg +Tested-by: BuildBot +Reviewed-by: Benjamin Kaduk +Reviewed-by: Stephan Wiesand +(cherry picked from commit 2fd2c69257edff968ef24a1d903bd602817bbf01) +--- + src/afs/LINUX/osi_vnodeops.c | 29 ++++++++++++++++++++++++++++- + 1 file changed, 28 insertions(+), 1 deletion(-) + +diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c +index 4d29efb..9a164ea 100644 +--- a/src/afs/LINUX/osi_vnodeops.c ++++ b/src/afs/LINUX/osi_vnodeops.c +@@ -1231,10 +1231,37 @@ afs_linux_dentry_revalidate(struct dentry *dp, int flags) + if (hgetlo(pvcp->f.m.DataVersion) > dp->d_time || !(vcp->f.states & CStatd)) { + struct vattr *vattr = NULL; + int code; ++ int lookup_good; + + credp = crref(); + code = afs_lookup(pvcp, (char *)dp->d_name.name, &tvc, credp); +- if (code || tvc != vcp) { ++ ++ if (code) { ++ /* We couldn't perform the lookup, so we're not okay. */ ++ lookup_good = 0; ++ ++ } else if (tvc == vcp) { ++ /* We got back the same vcache, so we're good. */ ++ lookup_good = 1; ++ ++ } else if (tvc == VTOAFS(dp->d_inode)) { ++ /* We got back the same vcache, so we're good. This is ++ * different from the above case, because sometimes 'vcp' is ++ * not the same as the vcache for dp->d_inode, if 'vcp' was a ++ * mtpt and we evaluated it to a root dir. In rare cases, ++ * afs_lookup might not evalute the mtpt when we do, or vice ++ * versa, so the previous case will not succeed. But this is ++ * still 'correct', so make sure not to mark the dentry as ++ * invalid; it still points to the same thing! */ ++ lookup_good = 1; ++ ++ } else { ++ /* We got back a different file, so we're definitely not ++ * okay. */ ++ lookup_good = 0; ++ } ++ ++ if (!lookup_good) { + dput(parent); + /* Force unhash; the name doesn't point to this file + * anymore. */ diff --git a/debian/patches/0008-Linux-3.18-d_invalidate-can-no-longer-return-an-erro.patch b/debian/patches/0008-Linux-3.18-d_invalidate-can-no-longer-return-an-erro.patch new file mode 100644 index 000000000..4ff27558f --- /dev/null +++ b/debian/patches/0008-Linux-3.18-d_invalidate-can-no-longer-return-an-erro.patch @@ -0,0 +1,102 @@ +From: Marc Dionne +Date: Thu, 23 Oct 2014 11:12:57 -0400 +Subject: Linux 3.18: d_invalidate can no longer return an error + +d_invalidate is now defined as void and does not have +a return value to check. + +Reviewed-on: http://gerrit.openafs.org/11562 +Tested-by: BuildBot +Reviewed-by: D Brashear +(cherry picked from commit a42f01d5ebb13da575b3123800ee6990743155ab) + +Change-Id: I8542404771c4a7962238efd9a53d7dfcf4011c96 +Reviewed-on: http://gerrit.openafs.org/11569 +Reviewed-by: Anders Kaseorg +Tested-by: BuildBot +Reviewed-by: Benjamin Kaduk +Reviewed-by: Andrew Deason +Reviewed-by: Stephan Wiesand +(cherry picked from commit b3527c802ad82cdecc0df6dfa42b228710ad5fd4) +--- + acinclude.m4 | 1 + + src/afs/LINUX/osi_compat.h | 11 +++++++++++ + src/afs/LINUX/osi_vcache.c | 4 +++- + src/cf/linux-test4.m4 | 13 +++++++++++++ + 4 files changed, 28 insertions(+), 1 deletion(-) + +diff --git a/acinclude.m4 b/acinclude.m4 +index 13d70db..b10cfb6 100644 +--- a/acinclude.m4 ++++ b/acinclude.m4 +@@ -1024,6 +1024,7 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) + LINUX_IOP_I_CREATE_TAKES_BOOL + LINUX_DOP_D_REVALIDATE_TAKES_UNSIGNED + LINUX_IOP_LOOKUP_TAKES_UNSIGNED ++ LINUX_D_INVALIDATE_IS_VOID + + dnl If we are guaranteed that keyrings will work - that is + dnl a) The kernel has keyrings enabled +diff --git a/src/afs/LINUX/osi_compat.h b/src/afs/LINUX/osi_compat.h +index c500c61..26673a7 100644 +--- a/src/afs/LINUX/osi_compat.h ++++ b/src/afs/LINUX/osi_compat.h +@@ -557,4 +557,15 @@ afs_maybe_shrink_dcache(struct dentry *dp) + #endif + } + ++static inline int ++afs_d_invalidate(struct dentry *dp) ++{ ++#if defined(D_INVALIDATE_IS_VOID) ++ d_invalidate(dp); ++ return 0; ++#else ++ return d_invalidate(dp); ++#endif ++} ++ + #endif /* AFS_LINUX_OSI_COMPAT_H */ +diff --git a/src/afs/LINUX/osi_vcache.c b/src/afs/LINUX/osi_vcache.c +index 99aab91..1d0db82 100644 +--- a/src/afs/LINUX/osi_vcache.c ++++ b/src/afs/LINUX/osi_vcache.c +@@ -13,6 +13,8 @@ + #include "afs/sysincludes.h" /*Standard vendor system headers */ + #include "afsincludes.h" /*AFS-based standard headers */ + ++#include "osi_compat.h" ++ + int + osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep) { + int code; +@@ -71,7 +73,7 @@ restart: + dget(dentry); + + spin_unlock(&inode->i_lock); +- if (d_invalidate(dentry) == -EBUSY) { ++ if (afs_d_invalidate(dentry) == -EBUSY) { + dput(dentry); + /* perhaps lock and try to continue? (use cur as head?) */ + goto inuse; +diff --git a/src/cf/linux-test4.m4 b/src/cf/linux-test4.m4 +index 1759d9e..34c5d4d 100644 +--- a/src/cf/linux-test4.m4 ++++ b/src/cf/linux-test4.m4 +@@ -786,3 +786,16 @@ AC_DEFUN([LINUX_IOP_LOOKUP_TAKES_UNSIGNED], [ + [define if your iops.lookup takes an unsigned int argument], + [-Werror]) + ]) ++ ++ ++AC_DEFUN([LINUX_D_INVALIDATE_IS_VOID], [ ++ AC_CHECK_LINUX_BUILD([whether d_invalidate returns void], ++ [ac_cv_linux_func_d_invalidate_returns_void], ++ [#include ], ++ [ ++ void d_invalidate(struct dentry *); ++ ], ++ [D_INVALIDATE_IS_VOID], ++ [define if your d_invalidate returns void], ++ []) ++]) diff --git a/debian/patches/0009-Linux-3.18-key_type-no-longer-has-a-match-op.patch b/debian/patches/0009-Linux-3.18-key_type-no-longer-has-a-match-op.patch new file mode 100644 index 000000000..a841fe812 --- /dev/null +++ b/debian/patches/0009-Linux-3.18-key_type-no-longer-has-a-match-op.patch @@ -0,0 +1,72 @@ +From: Marc Dionne +Date: Thu, 23 Oct 2014 11:27:55 -0400 +Subject: Linux 3.18: key_type no longer has a match op + +Structure key_type no longer has a match op, and +overriding the default matching has to be done +differently. + +Our current match op doesn't do anything special so there's +no need to try to override the defaults; just remove the +assignment of .match and the associated function. + +Reviewed-on: http://gerrit.openafs.org/11563 +Tested-by: BuildBot +Reviewed-by: D Brashear +(cherry picked from commit b5de4a9f42bb83ae03f2f647b11a1200a502d013) + +Change-Id: I7baca4a7f02eac45671e1e9ebf48534cdd5830be +Reviewed-on: http://gerrit.openafs.org/11570 +Reviewed-by: Anders Kaseorg +Tested-by: BuildBot +Reviewed-by: Benjamin Kaduk +Reviewed-by: Andrew Deason +Reviewed-by: Stephan Wiesand +(cherry picked from commit 9d653bd966b47223eaaf6f8a5d983b6634bdf0d5) +--- + acinclude.m4 | 3 ++- + src/afs/LINUX/osi_groups.c | 4 ++++ + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/acinclude.m4 b/acinclude.m4 +index b10cfb6..72dd6c1 100644 +--- a/acinclude.m4 ++++ b/acinclude.m4 +@@ -840,8 +840,9 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) + AC_CHECK_LINUX_STRUCT([file_operations], [sendfile], [fs.h]) + AC_CHECK_LINUX_STRUCT([file_system_type], [mount], [fs.h]) + AC_CHECK_LINUX_STRUCT([inode_operations], [truncate], [fs.h]) +- AC_CHECK_LINUX_STRUCT([key_type], [preparse], [key-type.h]) + AC_CHECK_LINUX_STRUCT([key_type], [instantiate_prep], [key-type.h]) ++ AC_CHECK_LINUX_STRUCT([key_type], [match], [key-type.h]) ++ AC_CHECK_LINUX_STRUCT([key_type], [preparse], [key-type.h]) + AC_CHECK_LINUX_STRUCT([nameidata], [path], [namei.h]) + AC_CHECK_LINUX_STRUCT([proc_dir_entry], [owner], [proc_fs.h]) + AC_CHECK_LINUX_STRUCT([super_block], [s_bdi], [fs.h]) +diff --git a/src/afs/LINUX/osi_groups.c b/src/afs/LINUX/osi_groups.c +index f3f87c2..f1d97a6 100644 +--- a/src/afs/LINUX/osi_groups.c ++++ b/src/afs/LINUX/osi_groups.c +@@ -498,10 +498,12 @@ error: + return code; + } + ++#if defined(STRUCT_KEY_TYPE_HAS_MATCH) + static int afs_pag_match(const struct key *key, const void *description) + { + return strcmp(key->description, description) == 0; + } ++#endif + + static void afs_pag_destroy(struct key *key) + { +@@ -527,7 +529,9 @@ struct key_type key_type_afs_pag = + #else + .instantiate = afs_pag_instantiate, + #endif ++#if defined(STRUCT_KEY_TYPE_HAS_MATCH) + .match = afs_pag_match, ++#endif + .destroy = afs_pag_destroy, + }; + diff --git a/debian/patches/0010-LINUX-Avoid-check-for-key_type.match-existence.patch b/debian/patches/0010-LINUX-Avoid-check-for-key_type.match-existence.patch new file mode 100644 index 000000000..586de941e --- /dev/null +++ b/debian/patches/0010-LINUX-Avoid-check-for-key_type.match-existence.patch @@ -0,0 +1,97 @@ +From: Andrew Deason +Date: Wed, 5 Nov 2014 10:22:00 -0600 +Subject: LINUX: Avoid check for key_type.match existence + +Commit b5de4a9f removed our key_type 'match' function for kernels that +do not have such a 'match' function pointer. However, this added a +configure test where we are supposed to fail for the "new" behavior, +which is discouraged. + +This causes an actual problem, because this test will fail on at least +RHEL5, due to arguably unrelated reasons (the header file for the +relevant struct is in key.h instead of key-type.h). And so, in that +situation we avoid defining a 'match' function callback, meaning our +'match' function callback is NULL, which causes a panic when we try to +actually look up keys for a PAG. + +To fix this, transform the 'match' config test into one where we +succeed for the "new" behavior. We do this by testing for the +existence of the new functionality that replaced the old 'match' +function, which is the match_preparse function (specifically, the +'cmp' field in the structure accepted by match_preparse). This should +cause unrelated compilation errors to cause us to revert to the "old" +behavior instead of the "new" behavior. At worst, this should cause +build issues if we get the config test wrong (since we will try to use +the 'match' function definition that does not exist), instead of +panicing at runtime. + +Note that while we test for key_type.match_preparse, we don't actually +use that function, since our 'match' functionality is the same as the +default behavior (according to b5de4a9f). So, we can avoid defining +any such function for newer kernels. + +Thanks to Stephan Wiesand for bisecting this issue. + +Reviewed-on: http://gerrit.openafs.org/11589 +Reviewed-by: Marc Dionne +Reviewed-by: Stephan Wiesand +Tested-by: BuildBot +Reviewed-by: Jeffrey Altman +(cherry picked from commit a9a3cb2efff7e6c020be4687b004d157bc070ac6) + +Change-Id: I59f40258c5ea35a59681f436095922d111e344f6 +Reviewed-on: http://gerrit.openafs.org/11595 +Tested-by: Anders Kaseorg +Reviewed-by: Anders Kaseorg +Tested-by: BuildBot +Reviewed-by: Marc Dionne +Reviewed-by: Benjamin Kaduk +Reviewed-by: Andrew Deason +Reviewed-by: Stephan Wiesand +(cherry picked from commit 9ff1cd92d023f9a949b499891f552b41cb0c52e4) +--- + acinclude.m4 | 2 +- + src/afs/LINUX/osi_groups.c | 10 ++++++++-- + 2 files changed, 9 insertions(+), 3 deletions(-) + +diff --git a/acinclude.m4 b/acinclude.m4 +index 72dd6c1..d324dc1 100644 +--- a/acinclude.m4 ++++ b/acinclude.m4 +@@ -841,7 +841,7 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) + AC_CHECK_LINUX_STRUCT([file_system_type], [mount], [fs.h]) + AC_CHECK_LINUX_STRUCT([inode_operations], [truncate], [fs.h]) + AC_CHECK_LINUX_STRUCT([key_type], [instantiate_prep], [key-type.h]) +- AC_CHECK_LINUX_STRUCT([key_type], [match], [key-type.h]) ++ AC_CHECK_LINUX_STRUCT([key_type], [match_preparse], [key-type.h]) + AC_CHECK_LINUX_STRUCT([key_type], [preparse], [key-type.h]) + AC_CHECK_LINUX_STRUCT([nameidata], [path], [namei.h]) + AC_CHECK_LINUX_STRUCT([proc_dir_entry], [owner], [proc_fs.h]) +diff --git a/src/afs/LINUX/osi_groups.c b/src/afs/LINUX/osi_groups.c +index f1d97a6..3b068e5 100644 +--- a/src/afs/LINUX/osi_groups.c ++++ b/src/afs/LINUX/osi_groups.c +@@ -498,7 +498,13 @@ error: + return code; + } + +-#if defined(STRUCT_KEY_TYPE_HAS_MATCH) ++#if !defined(STRUCT_KEY_TYPE_HAS_MATCH_PREPARSE) ++/* Note that we only define a ->match function if struct ++ * key_type.match_preparse does _not_ exist. If key_type.match_preparse does ++ * exist, we would use that to specify an alternative comparison function; but ++ * since we just rely on default behavior, we don't need to actually specify ++ * one. But for kernels with no such match_preparse function, we need to ++ * specify a 'match' function, since there is no default. */ + static int afs_pag_match(const struct key *key, const void *description) + { + return strcmp(key->description, description) == 0; +@@ -529,7 +535,7 @@ struct key_type key_type_afs_pag = + #else + .instantiate = afs_pag_instantiate, + #endif +-#if defined(STRUCT_KEY_TYPE_HAS_MATCH) ++#if !defined(STRUCT_KEY_TYPE_HAS_MATCH_PREPARSE) + .match = afs_pag_match, + #endif + .destroy = afs_pag_destroy, diff --git a/debian/patches/0011-Unix-CM-Avoid-using-stale-DV-in-afs_StoreAllSegments.patch b/debian/patches/0011-Unix-CM-Avoid-using-stale-DV-in-afs_StoreAllSegments.patch new file mode 100644 index 000000000..5f4c27c5d --- /dev/null +++ b/debian/patches/0011-Unix-CM-Avoid-using-stale-DV-in-afs_StoreAllSegments.patch @@ -0,0 +1,74 @@ +From: Marc Dionne +Date: Fri, 19 Dec 2014 10:11:53 -0500 +Subject: Unix CM: Avoid using stale DV in afs_StoreAllSegments + +It was reported in RT 131976 that on Linux some file +corruption was observed when doing mmap writes to +a file substantially larger than the cache size. + +osi_VM_StoreAllSegments drops locks and asks the OS to flush +any dirty pages in the file 's mapping. This will trigger +calls into our writepage op, and if the number of dirty +cache chunks is too high (as will happen for a file larger +than the cache size), afs_DoPartialWrite will recursively +call afs_StoreAllSegments and some chunks will be written +back to the server. After potentially doing this several +times, control will return to the original afs_StoreAllSegments. + +At that point the data version that was stored before +osi_VM_StoreAllSegments is no longer correct, leading to +possible data corruption. + +Triggering this bug requires writing a file larger than the +cache so that partial stores are done, and writing enough +data to exceed the system's maximum dirty ratio and cause +it to initiate writeback. + +To fix, just wait until after osi_VM_StoreAllSegments to +look at and store the data version + +FIXES 131976 + +Reviewed-on: http://gerrit.openafs.org/11644 +Tested-by: BuildBot +Reviewed-by: Jeffrey Altman +(cherry picked from commit b22c586bcdf785c489009ab96cbb572181cb9b09) + +Change-Id: I32a2f6f32d432fe4a2e21ebd4bb278a9d7e5499f +Reviewed-on: http://gerrit.openafs.org/11656 +Tested-by: BuildBot +Reviewed-by: Benjamin Kaduk +Reviewed-by: Stephan Wiesand +(cherry picked from commit 013e8db33fbec8b5db4ac5a1ec94a7f5b2afbc45) +--- + src/afs/afs_segments.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/src/afs/afs_segments.c b/src/afs/afs_segments.c +index f407b49..1ea3311 100644 +--- a/src/afs/afs_segments.c ++++ b/src/afs/afs_segments.c +@@ -174,8 +174,6 @@ afs_StoreAllSegments(struct vcache *avc, struct vrequest *areq, + + AFS_STATCNT(afs_StoreAllSegments); + +- hset(oldDV, avc->f.m.DataVersion); +- hset(newDV, avc->f.m.DataVersion); + hash = DVHash(&avc->f.fid); + foreign = (avc->f.states & CForeign); + dcList = (struct dcache **)osi_AllocLargeSpace(AFS_LRALLOCSIZ); +@@ -213,6 +211,14 @@ afs_StoreAllSegments(struct vcache *avc, struct vrequest *areq, + /*printf("Net down in afs_StoreSegments\n");*/ + return ENETDOWN; + } ++ ++ /* ++ * Can't do this earlier because osi_VM_StoreAllSegments drops locks ++ * and can indirectly do some stores that increase the DV. ++ */ ++ hset(oldDV, avc->f.m.DataVersion); ++ hset(newDV, avc->f.m.DataVersion); ++ + ConvertWToSLock(&avc->lock); + + /* diff --git a/debian/patches/0012-afs-Fix-some-afs_conn-overcounts.patch b/debian/patches/0012-afs-Fix-some-afs_conn-overcounts.patch new file mode 100644 index 000000000..49ca5d29b --- /dev/null +++ b/debian/patches/0012-afs-Fix-some-afs_conn-overcounts.patch @@ -0,0 +1,84 @@ +From: Andrew Deason +Date: Sun, 14 Sep 2014 14:10:11 -0500 +Subject: afs: Fix some afs_conn overcounts + +The usual pattern of using afs_Conn looks like this: + + do { + tc = afs_Conn(...); + if (tc) { + code = /* ... */ + } else { + code = -1; + } + } while (afs_Analyze(...)); + +The afs_Analyze call, amongst other things, puts back the reference to +the connection obtained from afs_Conn. If anything inside the do/while +block exits that block without calling afs_Analyze or afs_PutConn, we +will leak a reference to the conn. + +A few places currently do this, by jumping out of the loop with +'goto's. Specifically, in afs_dcache.c and afs_bypasscache.c. These +locations currently leak references to our connection object (and to +the underlying Rx connection object), which can cause problems over +time. Specifically, this can cause a panic when the refcount overflows +and becomes negative, causing a panic message that looks like: + + afs_PutConn: refcount imbalance 0xd34db33f -32768 + +To avoid this, make sure we afs_PutConn in these cases where we 'goto' +out of the afs_Conn/afs_Analyze loop. Perhaps ideally we should cause +afs_Analyze itself to be called in these situations, but for now just +fix the problem with the least amount of impact possible. + +FIXES 131885 + +Reviewed-on: http://gerrit.openafs.org/11464 +Reviewed-by: Benjamin Kaduk +Reviewed-by: Daria Brashear +Tested-by: Benjamin Kaduk +Reviewed-by: Jeffrey Altman +(cherry picked from commit 54c0ee608f4afd2b178c9b60eabfc3564293d996) + +Change-Id: Ic02ede4f8177863e8079b4a92c9bad492d6dc97b +Reviewed-on: http://gerrit.openafs.org/11645 +Reviewed-by: Benjamin Kaduk +Reviewed-by: Daria Brashear +Tested-by: BuildBot +(cherry picked from commit fba39040435afe63b0737945e2269375107fc686) +--- + src/afs/afs_bypasscache.c | 1 + + src/afs/afs_dcache.c | 7 +++++++ + 2 files changed, 8 insertions(+) + +diff --git a/src/afs/afs_bypasscache.c b/src/afs/afs_bypasscache.c +index 744feb2..8fc6009 100644 +--- a/src/afs/afs_bypasscache.c ++++ b/src/afs/afs_bypasscache.c +@@ -637,6 +637,7 @@ afs_PrefetchNoCache(struct vcache *avc, + } else { + afs_warn("BYPASS: StartRXAFS_FetchData failed: %d\n", code); + unlock_and_release_pages(auio); ++ afs_PutConn(tc, rxconn, SHARED_LOCK); + goto done; + } + if (code == 0) { +diff --git a/src/afs/afs_dcache.c b/src/afs/afs_dcache.c +index dc1e039..a156e22 100644 +--- a/src/afs/afs_dcache.c ++++ b/src/afs/afs_dcache.c +@@ -2399,6 +2399,13 @@ afs_GetDCache(struct vcache *avc, afs_size_t abyte, + afs_PutDCache(tdc); + tdc = 0; + ReleaseReadLock(&avc->lock); ++ ++ if (tc) { ++ /* If we have a connection, we must put it back, ++ * since afs_Analyze will not be called here. */ ++ afs_PutConn(tc, rxconn, SHARED_LOCK); ++ } ++ + slowPass = 1; + goto RetryGetDCache; + } diff --git a/debian/patches/0013-Linux-Move-code-to-reset-the-root-to-afs-LINUX.patch b/debian/patches/0013-Linux-Move-code-to-reset-the-root-to-afs-LINUX.patch new file mode 100644 index 000000000..4fcff8bdb --- /dev/null +++ b/debian/patches/0013-Linux-Move-code-to-reset-the-root-to-afs-LINUX.patch @@ -0,0 +1,257 @@ +From: Marc Dionne +Date: Thu, 18 Dec 2014 06:57:22 -0500 +Subject: Linux: Move code to reset the root to afs/LINUX +MIME-Version: 1.0 +Content-Type: text/plain; charset="utf-8" +Content-Transfer-Encoding: 8bit + +Move the Linux specific bit of code to reset the root to +afs/LINUX platform specific files. Things that play with +the Linux vfs internals should not be exposed here. + +No functional change, but this helps cleanup some ifdef +mess. + +Reviewed-on: http://gerrit.openafs.org/11641 +Tested-by: BuildBot +Reviewed-by: Michael Laß +Reviewed-by: Daria Brashear +(cherry picked from commit 6ca324e565c34d9d04f3c553b7d0febe675ae538) + +Change-Id: I82803669dd34d7abeb29040fbb38ec2f000f2601 +Reviewed-on: http://gerrit.openafs.org/11658 +Tested-by: BuildBot +Reviewed-by: Chas Williams - CONTRACTOR +Reviewed-by: Daria Brashear +Reviewed-by: Stephan Wiesand +(cherry picked from commit a6013738362f4d1487ca57282b2428e3ba962720) +--- + src/afs/LINUX/osi_prototypes.h | 3 ++ + src/afs/LINUX/osi_vcache.c | 61 ++++++++++++++++++++++++++++++++++++ + src/afs/LINUX24/osi_prototypes.h | 3 ++ + src/afs/LINUX24/osi_vcache.c | 36 +++++++++++++++++++++ + src/afs/afs_daemons.c | 67 +++------------------------------------- + 5 files changed, 108 insertions(+), 62 deletions(-) + +diff --git a/src/afs/LINUX/osi_prototypes.h b/src/afs/LINUX/osi_prototypes.h +index 9002882..1d2ca0d 100644 +--- a/src/afs/LINUX/osi_prototypes.h ++++ b/src/afs/LINUX/osi_prototypes.h +@@ -79,6 +79,9 @@ extern void osi_VM_FlushPages(struct vcache *avc, afs_ucred_t *credp); + extern void osi_VM_Truncate(struct vcache *avc, int alen, + afs_ucred_t *acred); + ++/* osi_vcache.c */ ++extern void osi_ResetRootVCache(afs_uint32 volid); ++ + /* osi_vfsops.c */ + extern void vattr2inode(struct inode *ip, struct vattr *vp); + extern int afs_init_inodecache(void); +diff --git a/src/afs/LINUX/osi_vcache.c b/src/afs/LINUX/osi_vcache.c +index 1d0db82..391e7d4 100644 +--- a/src/afs/LINUX/osi_vcache.c ++++ b/src/afs/LINUX/osi_vcache.c +@@ -143,3 +143,64 @@ osi_PostPopulateVCache(struct vcache *avc) { + vSetType(avc, VREG); + } + ++/** ++ * osi_ResetRootVCache - Reset the root vcache ++ * Reset the dentry associated with the afs root. ++ * Called from afs_CheckRootVolume when we notice that ++ * the root volume ID has changed. ++ * ++ * @volid: volume ID for the afs root ++ */ ++void ++osi_ResetRootVCache(afs_uint32 volid) ++{ ++ struct vrequest *treq = NULL; ++ struct vattr vattr; ++ cred_t *credp; ++ struct dentry *dp; ++ struct vcache *vcp; ++ struct inode *root = AFSTOV(afs_globalVp); ++ ++ afs_rootFid.Fid.Volume = volid; ++ afs_rootFid.Fid.Vnode = 1; ++ afs_rootFid.Fid.Unique = 1; ++ ++ credp = crref(); ++ if (afs_CreateReq(&treq, credp)) ++ goto out; ++ vcp = afs_GetVCache(&afs_rootFid, treq, NULL, NULL); ++ if (!vcp) ++ goto out; ++ afs_getattr(vcp, &vattr, credp); ++ afs_fill_inode(AFSTOV(vcp), &vattr); ++ ++ dp = d_find_alias(root); ++ ++#if defined(HAVE_DCACHE_LOCK) ++ spin_lock(&dcache_lock); ++#else ++ spin_lock(&AFSTOV(vcp)->i_lock); ++#endif ++ spin_lock(&dp->d_lock); ++#if defined(D_ALIAS_IS_HLIST) ++ hlist_del_init(&dp->d_alias); ++ hlist_add_head(&dp->d_alias, &(AFSTOV(vcp)->i_dentry)); ++#else ++ list_del_init(&dp->d_alias); ++ list_add(&dp->d_alias, &(AFSTOV(vcp)->i_dentry)); ++#endif ++ dp->d_inode = AFSTOV(vcp); ++ spin_unlock(&dp->d_lock); ++#if defined(HAVE_DCACHE_LOCK) ++ spin_unlock(&dcache_lock); ++#else ++ spin_unlock(&AFSTOV(vcp)->i_lock); ++#endif ++ dput(dp); ++ ++ AFS_RELE(root); ++ afs_globalVp = vcp; ++out: ++ crfree(credp); ++ afs_DestroyReq(treq); ++} +diff --git a/src/afs/LINUX24/osi_prototypes.h b/src/afs/LINUX24/osi_prototypes.h +index ad2522c..39d6402 100644 +--- a/src/afs/LINUX24/osi_prototypes.h ++++ b/src/afs/LINUX24/osi_prototypes.h +@@ -69,6 +69,9 @@ extern void osi_syscall_clean(void); + extern int osi_sysctl_init(void); + extern void osi_sysctl_clean(void); + ++/* osi_vcache.c */ ++extern void osi_ResetRootVCache(afs_uint32 volid); ++ + /* osi_vm.c */ + extern int osi_VM_FlushVCache(struct vcache *avc, int *slept); + extern void osi_VM_TryToSmush(struct vcache *avc, afs_ucred_t *acred, +diff --git a/src/afs/LINUX24/osi_vcache.c b/src/afs/LINUX24/osi_vcache.c +index bbaf5ce..853a357 100644 +--- a/src/afs/LINUX24/osi_vcache.c ++++ b/src/afs/LINUX24/osi_vcache.c +@@ -119,3 +119,39 @@ osi_PostPopulateVCache(struct vcache *avc) { + vSetType(avc, VREG); + } + ++void ++osi_ResetRootVCache(afs_uint32 volid) ++{ ++ struct vrequest *treq = NULL; ++ struct vattr vattr; ++ cred_t *credp; ++ struct dentry *dp; ++ struct vcache *vcp; ++ ++ afs_rootFid.Fid.Volume = volid; ++ afs_rootFid.Fid.Vnode = 1; ++ afs_rootFid.Fid.Unique = 1; ++ ++ credp = crref(); ++ if (afs_CreateReq(&treq, credp)) ++ goto out; ++ vcp = afs_GetVCache(&afs_rootFid, treq, NULL, NULL); ++ if (!vcp) ++ goto out; ++ afs_getattr(vcp, &vattr, credp); ++ afs_fill_inode(AFSTOV(vcp), &vattr); ++ ++ dp = d_find_alias(AFSTOV(afs_globalVp)); ++ spin_lock(&dcache_lock); ++ list_del_init(&dp->d_alias); ++ list_add(&dp->d_alias, &(AFSTOV(vcp)->i_dentry)); ++ dp->d_inode = AFSTOV(vcp); ++ spin_unlock(&dcache_lock); ++ dput(dp); ++ ++ AFS_FAST_RELE(afs_globalVp); ++ afs_globalVp = vcp; ++out: ++ crfree(credp); ++ afs_DestroyReq(treq); ++} +diff --git a/src/afs/afs_daemons.c b/src/afs/afs_daemons.c +index 8e5f6ad..c26cdee 100644 +--- a/src/afs/afs_daemons.c ++++ b/src/afs/afs_daemons.c +@@ -363,71 +363,14 @@ afs_CheckRootVolume(void) + * count to zero and fs checkv is executed when the current + * directory is /afs. + */ +-#ifdef AFS_LINUX20_ENV +- { +- struct vrequest *treq = NULL; +- struct vattr vattr; +- cred_t *credp; +- struct dentry *dp; +- struct vcache *vcp; +- +- afs_rootFid.Fid.Volume = volid; +- afs_rootFid.Fid.Vnode = 1; +- afs_rootFid.Fid.Unique = 1; +- +- credp = crref(); +- if (afs_CreateReq(&treq, credp)) +- goto out; +- vcp = afs_GetVCache(&afs_rootFid, treq, NULL, NULL); +- if (!vcp) +- goto out; +- afs_getattr(vcp, &vattr, credp); +- afs_fill_inode(AFSTOV(vcp), &vattr); +- +- dp = d_find_alias(AFSTOV(afs_globalVp)); +- +-#if defined(AFS_LINUX24_ENV) +-#if defined(HAVE_DCACHE_LOCK) +- spin_lock(&dcache_lock); +-#else +- spin_lock(&AFSTOV(vcp)->i_lock); +-#endif +-#if defined(AFS_LINUX26_ENV) +- spin_lock(&dp->d_lock); +-#endif +-#endif +-#if defined(D_ALIAS_IS_HLIST) +- hlist_del_init(&dp->d_alias); +- hlist_add_head(&dp->d_alias, &(AFSTOV(vcp)->i_dentry)); +-#else +- list_del_init(&dp->d_alias); +- list_add(&dp->d_alias, &(AFSTOV(vcp)->i_dentry)); +-#endif +- dp->d_inode = AFSTOV(vcp); +-#if defined(AFS_LINUX24_ENV) +-#if defined(AFS_LINUX26_ENV) +- spin_unlock(&dp->d_lock); +-#endif +-#if defined(HAVE_DCACHE_LOCK) +- spin_unlock(&dcache_lock); +-#else +- spin_unlock(&AFSTOV(vcp)->i_lock); +-#endif +-#endif +- dput(dp); +- +- AFS_FAST_RELE(afs_globalVp); +- afs_globalVp = vcp; +- out: +- crfree(credp); +- afs_DestroyReq(treq); +- } ++#ifdef AFS_LINUX22_ENV ++ osi_ResetRootVCache(volid); + #else +-#ifdef AFS_DARWIN80_ENV ++# ifdef AFS_DARWIN80_ENV + afs_PutVCache(afs_globalVp); +-#else ++# else + AFS_FAST_RELE(afs_globalVp); +-#endif ++# endif + afs_globalVp = 0; + #endif + } diff --git a/debian/patches/0014-Linux-d_alias-becomes-d_u.d_alias.patch b/debian/patches/0014-Linux-d_alias-becomes-d_u.d_alias.patch new file mode 100644 index 000000000..d74b7e54f --- /dev/null +++ b/debian/patches/0014-Linux-d_alias-becomes-d_u.d_alias.patch @@ -0,0 +1,89 @@ +From: Marc Dionne +Date: Thu, 18 Dec 2014 07:13:46 -0500 +Subject: Linux: d_alias becomes d_u.d_alias +MIME-Version: 1.0 +Content-Type: text/plain; charset="utf-8" +Content-Transfer-Encoding: 8bit + +The fields in struct dentry are re-arranged so that d_alias +shares space wth d_rcu inside the d_u union. Some references +need to change from d_alias to d_u.d_alias. + +The kernel change was introduced for 3.19 but was also backported +to the 3.18 stable series in 3.18.1, so this commit is required +for 3.19 and current 3.18 kernels. + +Reviewed-on: http://gerrit.openafs.org/11642 +Reviewed-by: Anders Kaseorg +Reviewed-by: Michael Laß +Reviewed-by: Daria Brashear +Tested-by: BuildBot +(cherry picked from commit d6f29679098aff171e69511823b340ccf28e5c31) + +Change-Id: Ifb6199aa7fa922e64540d9fad1d2d79facbb9761 +Reviewed-on: http://gerrit.openafs.org/11659 +Reviewed-by: Chas Williams - CONTRACTOR +Tested-by: BuildBot +Reviewed-by: Daria Brashear +Reviewed-by: Stephan Wiesand +(cherry picked from commit 860764da5ee2e48a2c3f7552fad1766e19eae47f) +--- + acinclude.m4 | 1 + + src/afs/LINUX/osi_compat.h | 4 ++++ + src/cf/linux-test4.m4 | 9 ++++++++- + 3 files changed, 13 insertions(+), 1 deletion(-) + +diff --git a/acinclude.m4 b/acinclude.m4 +index d324dc1..fa429c7 100644 +--- a/acinclude.m4 ++++ b/acinclude.m4 +@@ -828,6 +828,7 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) + [backing-dev.h]) + AC_CHECK_LINUX_STRUCT([cred], [session_keyring], [cred.h]) + AC_CHECK_LINUX_STRUCT([ctl_table], [ctl_name], [sysctl.h]) ++ AC_CHECK_LINUX_STRUCT([dentry], [d_u.d_alias], [dcache.h]) + AC_CHECK_LINUX_STRUCT([dentry_operations], [d_automount], [dcache.h]) + AC_CHECK_LINUX_STRUCT([inode], [i_alloc_sem], [fs.h]) + AC_CHECK_LINUX_STRUCT([inode], [i_blkbits], [fs.h]) +diff --git a/src/afs/LINUX/osi_compat.h b/src/afs/LINUX/osi_compat.h +index 26673a7..b98e980 100644 +--- a/src/afs/LINUX/osi_compat.h ++++ b/src/afs/LINUX/osi_compat.h +@@ -37,6 +37,10 @@ typedef struct vfs_path afs_linux_path_t; + typedef struct path afs_linux_path_t; + #endif + ++#if defined(STRUCT_DENTRY_HAS_D_U_D_ALIAS) ++# define d_alias d_u.d_alias ++#endif ++ + #ifndef HAVE_LINUX_DO_SYNC_READ + static inline int + do_sync_read(struct file *fp, char *buf, size_t count, loff_t *offp) { +diff --git a/src/cf/linux-test4.m4 b/src/cf/linux-test4.m4 +index 34c5d4d..5f5ec5c 100644 +--- a/src/cf/linux-test4.m4 ++++ b/src/cf/linux-test4.m4 +@@ -723,7 +723,11 @@ AC_DEFUN([LINUX_D_ALIAS_IS_HLIST], [ + [#include ], + [struct dentry *d = NULL; + struct hlist_node *hn = NULL; +- d->d_alias = *hn;], ++ #if defined(STRUCT_DENTRY_HAS_D_U_D_ALIAS) ++ d->d_u.d_alias = *hn; ++ #else ++ d->d_alias = *hn; ++ #endif], + [D_ALIAS_IS_HLIST], + [define if dentry->d_alias is an hlist], + []) +@@ -737,6 +741,9 @@ AC_DEFUN([LINUX_HLIST_ITERATOR_NO_NODE], [ + #include ], + [struct dentry *d = NULL, *cur; + struct inode *ip; ++ #if defined(STRUCT_DENTRY_HAS_D_U_D_ALIAS) ++ # define d_alias d_u.d_alias ++ #endif + hlist_for_each_entry(cur, &ip->i_dentry, d_alias) { } + ], + [HLIST_ITERATOR_NO_NODE], diff --git a/debian/patches/0015-Linux-3.19-No-more-f_dentry.patch b/debian/patches/0015-Linux-3.19-No-more-f_dentry.patch new file mode 100644 index 000000000..dfc0e5148 --- /dev/null +++ b/debian/patches/0015-Linux-3.19-No-more-f_dentry.patch @@ -0,0 +1,61 @@ +From: Marc Dionne +Date: Mon, 5 Jan 2015 07:03:16 -0500 +Subject: Linux 3.19: No more f_dentry + +Back in kernel 2.6 .20 struct file lost its f_dentry field +which was replaced by f_path.To ease transition f_dentry +was defined as f_dpath.dentry in the same header.This +define finally gets removed with kernel 3.19. + +Keep using f_dentry in the code, but add a configure test +for the presence of f_path and the absence of the f_dentry +macro so we can add it if its missing. + +Change - Id:I8e8a7e4d3ddd861018de50af1eb7315e730ad529 + +Reviewed-on: http://gerrit.openafs.org/11646 +Reviewed-by: Daria Brashear +Tested-by: BuildBot +(cherry picked from commit f9ca302b7a10ffc36f2439e068333ab147791c5a) + +Change-Id: I179bf2fbc22e824e40c60c59e5d223d49343e7a5 +Reviewed-on: http://gerrit.openafs.org/11660 +Reviewed-by: Chas Williams - CONTRACTOR +Tested-by: BuildBot +Reviewed-by: Daria Brashear +Reviewed-by: Stephan Wiesand +(cherry picked from commit 7ba61dfa6cedc4e6e106bd2079e564e554720d7e) +--- + acinclude.m4 | 1 + + src/afs/LINUX/osi_compat.h | 6 ++++++ + 2 files changed, 7 insertions(+) + +diff --git a/acinclude.m4 b/acinclude.m4 +index fa429c7..d2bb3b7 100644 +--- a/acinclude.m4 ++++ b/acinclude.m4 +@@ -835,6 +835,7 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) + AC_CHECK_LINUX_STRUCT([inode], [i_blksize], [fs.h]) + AC_CHECK_LINUX_STRUCT([inode], [i_mutex], [fs.h]) + AC_CHECK_LINUX_STRUCT([inode], [i_security], [fs.h]) ++ AC_CHECK_LINUX_STRUCT([file], [f_path], [fs.h]) + AC_CHECK_LINUX_STRUCT([file_operations], [flock], [fs.h]) + AC_CHECK_LINUX_STRUCT([file_operations], [iterate], [fs.h]) + AC_CHECK_LINUX_STRUCT([file_operations], [read_iter], [fs.h]) +diff --git a/src/afs/LINUX/osi_compat.h b/src/afs/LINUX/osi_compat.h +index b98e980..53b78b7 100644 +--- a/src/afs/LINUX/osi_compat.h ++++ b/src/afs/LINUX/osi_compat.h +@@ -41,6 +41,12 @@ typedef struct path afs_linux_path_t; + # define d_alias d_u.d_alias + #endif + ++#if defined(STRUCT_FILE_HAS_F_PATH) ++# if !defined(f_dentry) ++# define f_dentry f_path.dentry ++# endif ++#endif ++ + #ifndef HAVE_LINUX_DO_SYNC_READ + static inline int + do_sync_read(struct file *fp, char *buf, size_t count, loff_t *offp) { diff --git a/debian/patches/0016-Linux-3.19-Use-mgs_iter-in-struct-msghdr.patch b/debian/patches/0016-Linux-3.19-Use-mgs_iter-in-struct-msghdr.patch new file mode 100644 index 000000000..eb49d9bb5 --- /dev/null +++ b/debian/patches/0016-Linux-3.19-Use-mgs_iter-in-struct-msghdr.patch @@ -0,0 +1,54 @@ +From: Marc Dionne +Date: Mon, 5 Jan 2015 07:13:37 -0500 +Subject: Linux 3.19: Use mgs_iter in struct msghdr + +struct msghdr gets msg_iov replaced by msg_iter. Add a configure +test and adjust the affected code. + +Reviewed-on: http://gerrit.openafs.org/11647 +Reviewed-by: Daria Brashear +Tested-by: BuildBot +(cherry picked from commit ec9a7c2db833efacfd0692c658c2d38ed9f852ba) + +Change-Id: I9d873626d8997922aacf67a5a9ce7621ed904faa +Reviewed-on: http://gerrit.openafs.org/11661 +Reviewed-by: Chas Williams - CONTRACTOR +Tested-by: BuildBot +Reviewed-by: Daria Brashear +Reviewed-by: Stephan Wiesand +(cherry picked from commit 78e8cce68d11e895140b0b03894ffdd62699ffbc) +--- + acinclude.m4 | 1 + + src/rx/LINUX/rx_knet.c | 5 +++++ + 2 files changed, 6 insertions(+) + +diff --git a/acinclude.m4 b/acinclude.m4 +index d2bb3b7..46d1215 100644 +--- a/acinclude.m4 ++++ b/acinclude.m4 +@@ -845,6 +845,7 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) + AC_CHECK_LINUX_STRUCT([key_type], [instantiate_prep], [key-type.h]) + AC_CHECK_LINUX_STRUCT([key_type], [match_preparse], [key-type.h]) + AC_CHECK_LINUX_STRUCT([key_type], [preparse], [key-type.h]) ++ AC_CHECK_LINUX_STRUCT([msghdr], [msg_iter], [socket.h]) + AC_CHECK_LINUX_STRUCT([nameidata], [path], [namei.h]) + AC_CHECK_LINUX_STRUCT([proc_dir_entry], [owner], [proc_fs.h]) + AC_CHECK_LINUX_STRUCT([super_block], [s_bdi], [fs.h]) +diff --git a/src/rx/LINUX/rx_knet.c b/src/rx/LINUX/rx_knet.c +index cb7034e..3f7f2bc 100644 +--- a/src/rx/LINUX/rx_knet.c ++++ b/src/rx/LINUX/rx_knet.c +@@ -229,8 +229,13 @@ osi_NetReceive(osi_socket so, struct sockaddr_in *from, struct iovec *iov, + #endif + memcpy(tmpvec, iov, iovcnt * sizeof(struct iovec)); + msg.msg_name = from; ++#if defined(STRUCT_MSGHDR_HAS_MSG_ITER) ++ msg.msg_iter.iov = tmpvec; ++ msg.msg_iter.nr_segs = iovcnt; ++#else + msg.msg_iov = tmpvec; + msg.msg_iovlen = iovcnt; ++#endif + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; diff --git a/debian/patches/0017-Linux-3.19-struct-nameidata-becomes-opaque.patch b/debian/patches/0017-Linux-3.19-struct-nameidata-becomes-opaque.patch new file mode 100644 index 000000000..94e0aebbf --- /dev/null +++ b/debian/patches/0017-Linux-3.19-struct-nameidata-becomes-opaque.patch @@ -0,0 +1,84 @@ +From: Marc Dionne +Date: Mon, 5 Jan 2015 07:17:14 -0500 +Subject: Linux 3.19: struct nameidata becomes opaque + +With kernel 3.19 struct nameidata becomes opaque. As a result +we cannot rely on STRUCT_NAMEIDATA_HAS_PATH being true for +new kernels. + +Rework the conditions here so that STRUCT_NAMEIDATA_HAS_PATH +is only tested when we're using a nameidata structure and +the result matters. + +Also modify a configure test to use a nameidata pointer +instead of an actual structure. + +Reviewed-on: http://gerrit.openafs.org/11648 +Reviewed-by: Daria Brashear +Tested-by: BuildBot +(cherry picked from commit 72e22eb00f641f137f7dbe4195d6d82f4a8addc9) + +Change-Id: Ia794d9006a054d16a3b9e5b8ced55c798244d4c7 +Reviewed-on: http://gerrit.openafs.org/11662 +Reviewed-by: Chas Williams - CONTRACTOR +Tested-by: BuildBot +Reviewed-by: Daria Brashear +Reviewed-by: Stephan Wiesand +(cherry picked from commit 3da7b86c4ac998640b0b7ffd0e01613449d72e30) +--- + src/afs/LINUX/osi_compat.h | 16 ++++++++-------- + src/cf/linux-test4.m4 | 4 ++-- + 2 files changed, 10 insertions(+), 10 deletions(-) + +diff --git a/src/afs/LINUX/osi_compat.h b/src/afs/LINUX/osi_compat.h +index 53b78b7..c1cdb19 100644 +--- a/src/afs/LINUX/osi_compat.h ++++ b/src/afs/LINUX/osi_compat.h +@@ -475,23 +475,23 @@ afs_get_dentry_ref(struct nameidata *nd, struct vfsmount **mnt, struct dentry ** + #else + afs_get_dentry_ref(afs_linux_path_t *path, struct vfsmount **mnt, struct dentry **dpp) { + #endif +-#if defined(STRUCT_NAMEIDATA_HAS_PATH) +-# if defined(HAVE_LINUX_PATH_LOOKUP) ++#if defined(HAVE_LINUX_PATH_LOOKUP) ++# if defined(STRUCT_NAMEIDATA_HAS_PATH) + *dpp = dget(nd->path.dentry); + if (mnt) + *mnt = mntget(nd->path.mnt); + path_put(&nd->path); + # else +- *dpp = dget(path->dentry); +- if (mnt) +- *mnt = mntget(path->mnt); +- path_put(path); +-# endif +-#else + *dpp = dget(nd->dentry); + if (mnt) + *mnt = mntget(nd->mnt); + path_release(nd); ++# endif ++#else ++ *dpp = dget(path->dentry); ++ if (mnt) ++ *mnt = mntget(path->mnt); ++ path_put(path); + #endif + } + +diff --git a/src/cf/linux-test4.m4 b/src/cf/linux-test4.m4 +index 5f5ec5c..604d380 100644 +--- a/src/cf/linux-test4.m4 ++++ b/src/cf/linux-test4.m4 +@@ -278,9 +278,9 @@ AC_DEFUN([LINUX_IOP_I_PUT_LINK_TAKES_COOKIE], [ + #include ], + [struct inode _inode; + struct dentry _dentry; +-struct nameidata _nameidata; ++struct nameidata *_nameidata; + void *cookie; +-(void)_inode.i_op->put_link(&_dentry, &_nameidata, cookie);], ++(void)_inode.i_op->put_link(&_dentry, _nameidata, cookie);], + [IOP_PUT_LINK_TAKES_COOKIE], + [define if your iops.put_link takes a cookie], + []) diff --git a/debian/patches/0018-Linux-d_splice_alias-may-drop-inode-reference-on-err.patch b/debian/patches/0018-Linux-d_splice_alias-may-drop-inode-reference-on-err.patch new file mode 100644 index 000000000..7e7ccbf49 --- /dev/null +++ b/debian/patches/0018-Linux-d_splice_alias-may-drop-inode-reference-on-err.patch @@ -0,0 +1,138 @@ +From: Marc Dionne +Date: Thu, 18 Dec 2014 08:43:22 -0500 +Subject: Linux: d_splice_alias may drop inode reference on error +MIME-Version: 1.0 +Content-Type: text/plain; charset="utf-8" +Content-Transfer-Encoding: 8bit + +d_splice_alias now drops the inode reference on error, so we +need to grab an extra one to make sure that the inode doesn't +go away, and release it when done if there was no error. + +For kernels that may not drop the reference, provide an +additional iput() within an ifdef. This could be hooked up +to a configure option to allow building a module for a kernel +that is known not to drop the reference on error. That hook +is not provided here. Affected kernels should be the early +3.17 ones (3.17 - 3.17.2); 3.16 and older kernels should not +return errors here. + +[kaduk@mit.edu add configure option to control behavior, which +is mandatory on non-buildbot linux systems] + +Reviewed-on: http://gerrit.openafs.org/11643 +Tested-by: BuildBot +Reviewed-by: Michael Laß +Reviewed-by: Jeffrey Altman +(cherry picked from commit 15260c7fdc5ac8fe9fb1797c8e383c665e9e0ccd) + +Change-Id: I288eb66c38386fcd6bae0da111d97e211cc5c995 +(cherry picked from commit 33856e051b1eae40544c23fd88eb21801aef98bb) +--- + acinclude.m4 | 26 ++++++++++++++++++++++++++ + src/afs/LINUX/osi_vnodeops.c | 29 ++++++++++++++++++++++++++--- + 2 files changed, 52 insertions(+), 3 deletions(-) + +diff --git a/acinclude.m4 b/acinclude.m4 +index 46d1215..2e7b0ed 100644 +--- a/acinclude.m4 ++++ b/acinclude.m4 +@@ -232,6 +232,26 @@ AC_ARG_ENABLE([linux-syscall-probing], + , + [enable_linux_syscall_probing="maybe"]) + ++AC_ARG_ENABLE([linux-d_splice_alias-extra-iput], ++ [AS_HELP_STRING([--enable-linux-d_splice_alias-extra-iput], ++ [Linux has introduced an incompatible behavior change in the ++ d_splice_alias function with no reliable way to determine which ++ behavior will be produced. If Linux commit ++ 51486b900ee92856b977eacfc5bfbe6565028070 (or equivalent) has been ++ applied to your kernel, disable this option. If that commit is ++ not present in your kernel, enable this option. We apologize ++ that you are required to know this about your running kernel.])], ++ [], ++ [case $system in ++ *-linux*) ++ AS_IF([test "x$LOGNAME" != "xbuildslave" && ++ test "x$LOGNAME" != "xbuildbot"], ++ [AC_ERROR([Linux users must specify either ++ --enable-linux-d_splice_alias-extra-iput or ++ --disable-linux-d_splice_alias-extra-iput])], ++ [enable_linux_d_splice_alias_extra_iput="no"]) ++ esac ++ ]) + AC_ARG_WITH([xslt-processor], + AS_HELP_STRING([--with-xslt-processor=ARG], + [which XSLT processor to use (possible choices are: libxslt, saxon, xalan-j, xsltproc)]), +@@ -916,6 +936,9 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) + AC_CHECK_LINUX_FUNC([hlist_unhashed], + [#include ], + [hlist_unhashed(0);]) ++ AC_CHECK_LINUX_FUNC([ihold], ++ [#include ], ++ [ihold(NULL);]) + AC_CHECK_LINUX_FUNC([i_size_read], + [#include ], + [i_size_read(NULL);]) +@@ -1107,6 +1130,9 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) + fi + : + fi ++ if test "x$enable_linux_d_splice_alias_extra_iput" = xyes; then ++ AC_DEFINE(D_SPLICE_ALIAS_LEAK_ON_ERROR, 1, [for internal use]) ++ fi + dnl Linux-only, but just enable always. + AC_DEFINE(AFS_CACHE_BYPASS, 1, [define to activate cache bypassing Unix client]) + esac +diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c +index 9a164ea..760c9b8 100644 +--- a/src/afs/LINUX/osi_vnodeops.c ++++ b/src/afs/LINUX/osi_vnodeops.c +@@ -1549,6 +1549,17 @@ afs_linux_lookup(struct inode *dip, struct dentry *dp) + ip->i_flags |= S_AUTOMOUNT; + #endif + } ++ /* ++ * Take an extra reference so the inode doesn't go away if ++ * d_splice_alias drops our reference on error. ++ */ ++ if (ip) ++#ifdef HAVE_LINUX_IHOLD ++ ihold(ip); ++#else ++ igrab(ip); ++#endif ++ + newdp = d_splice_alias(ip, dp); + + done: +@@ -1562,14 +1573,26 @@ afs_linux_lookup(struct inode *dip, struct dentry *dp) + * d_splice_alias can return an error (EIO) if there is an existing + * connected directory alias for this dentry. + */ +- if (!IS_ERR(newdp)) ++ if (!IS_ERR(newdp)) { ++ iput(ip); + return newdp; +- else { ++ } else { + d_add(dp, ip); ++ /* ++ * Depending on the kernel version, d_splice_alias may or may ++ * not drop the inode reference on error. If it didn't, do it ++ * here. ++ */ ++#if defined(D_SPLICE_ALIAS_LEAK_ON_ERROR) ++ iput(ip); ++#endif + return NULL; + } +- } else ++ } else { ++ if (ip) ++ iput(ip); + return ERR_PTR(afs_convert_code(code)); ++ } + } + + static int diff --git a/debian/patches/series b/debian/patches/series index a55c8fbc1..fb9caaf4e 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -1,3 +1,18 @@ 0001-userok.c-Fix-fixed-size-on-stack-path-buffers.patch 0002-Tweak-AFSDIR_PATH_MAX-definition.patch 0003-Add-dummy-exit-command-for-afsd-to-do-nothing.patch +0004-Linux-3.17-No-more-typedef-for-ctl_table.patch +0005-Linux-3.17-Deal-with-d_splice_alias-errors.patch +0006-LINUX-Check-afs_lookup-return-code-explicitly.patch +0007-LINUX-Avoid-d_revalidate-failure-on-mtpt-mismatch.patch +0008-Linux-3.18-d_invalidate-can-no-longer-return-an-erro.patch +0009-Linux-3.18-key_type-no-longer-has-a-match-op.patch +0010-LINUX-Avoid-check-for-key_type.match-existence.patch +0011-Unix-CM-Avoid-using-stale-DV-in-afs_StoreAllSegments.patch +0012-afs-Fix-some-afs_conn-overcounts.patch +0013-Linux-Move-code-to-reset-the-root-to-afs-LINUX.patch +0014-Linux-d_alias-becomes-d_u.d_alias.patch +0015-Linux-3.19-No-more-f_dentry.patch +0016-Linux-3.19-Use-mgs_iter-in-struct-msghdr.patch +0017-Linux-3.19-struct-nameidata-becomes-opaque.patch +0018-Linux-d_splice_alias-may-drop-inode-reference-on-err.patch -- 2.39.5