From f0a0cbc4015bbb718d26030912f8fc35099508f9 Mon Sep 17 00:00:00 2001 From: Marc Dionne Date: Fri, 28 Jan 2011 19:41:32 -0500 Subject: [PATCH] Linux: 2.6.38: Adjust for permission inode operation changes The permission i_op has a new signature with a flags argument, and must now deal with RCU path walking. - Fix existing configure test for this i_op, it succeeds when it shouldn't - Add a new configure test for the new signature - Make our permission i_op "RCU-walk aware" - return ECHILD if called in that mode Reviewed-on: http://gerrit.openafs.org/3770 Tested-by: BuildBot Reviewed-by: Derrick Brashear (cherry picked from commit 5bcc0ea735ea519298c98b46c66bf1326cdee5e4) Change-Id: Iebfab65b3442ea286873e6af96f1c05c98e5d126 Signed-off-by: Anders Kaseorg Reviewed-on: http://gerrit.openafs.org/3997 Reviewed-by: Simon Wilkinson Tested-by: BuildBot Reviewed-by: Russ Allbery (cherry picked from commit 29855d9dc5d117ba106bdb0dd9a9bc6e0592c19c) --- acinclude.m4 | 1 + src/afs/LINUX/osi_vnodeops.c | 13 +++++++++++-- src/cf/linux-test4.m4 | 16 ++++++++++++++-- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 60c47d194..de8228350 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -768,6 +768,7 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) LINUX_WRITE_INODE_RETURN_TYPE LINUX_IOP_I_CREATE_TAKES_NAMEIDATA LINUX_IOP_I_LOOKUP_TAKES_NAMEIDATA + LINUX_IOP_I_PERMISSION_TAKES_FLAGS LINUX_IOP_I_PERMISSION_TAKES_NAMEIDATA LINUX_IOP_I_PUT_LINK_TAKES_COOKIE LINUX_DOP_D_REVALIDATE_TAKES_NAMEIDATA diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index 2389389c8..835276968 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -1786,16 +1786,25 @@ afs_linux_updatepage(struct file *fp, struct page *pp, unsigned long offset, * Check access rights - returns error if can't check or permission denied. */ static int -#ifdef IOP_PERMISSION_TAKES_NAMEIDATA +#if defined(IOP_PERMISSION_TAKES_FLAGS) +afs_linux_permission(struct inode *ip, int mode, unsigned int flags) +#elif defined(IOP_PERMISSION_TAKES_NAMEIDATA) afs_linux_permission(struct inode *ip, int mode, struct nameidata *nd) #else afs_linux_permission(struct inode *ip, int mode) #endif { int code; - cred_t *credp = crref(); + cred_t *credp; int tmp = 0; +#if defined(IOP_PERMISSION_TAKES_FLAGS) + /* We don't support RCU path walking */ + if (flags & IPERM_FLAG_RCU) + return -ECHILD; +#endif + + credp = crref(); AFS_GLOCK(); if (mode & MAY_EXEC) tmp |= VEXEC; diff --git a/src/cf/linux-test4.m4 b/src/cf/linux-test4.m4 index 67ddf913f..88e48636a 100644 --- a/src/cf/linux-test4.m4 +++ b/src/cf/linux-test4.m4 @@ -680,12 +680,24 @@ AC_DEFUN([LINUX_IOP_I_PERMISSION_TAKES_NAMEIDATA], [ [#include #include ], [struct inode _inode; -struct dentry _dentry; struct nameidata _nameidata; (void)_inode.i_op->permission(&_inode, 0, &_nameidata);], [IOP_PERMISSION_TAKES_NAMEIDATA], [define if your iops.permission takes a nameidata argument], - []) + [-Werror]) +]) + + +AC_DEFUN([LINUX_IOP_I_PERMISSION_TAKES_FLAGS], [ + AC_CHECK_LINUX_BUILD([whether inode_operations.permission takes flags], + [ac_cv_linux_func_i_permission_takes_flags], + [#include ], + [struct inode _inode; + unsigned int flags = 0; + (void)_inode.i_op->permission(&_inode, 0, flags);], + [IOP_PERMISSION_TAKES_FLAGS], + [define if your iops.permission takes a flags argument], + [-Werror]) ]) -- 2.39.5