From 29ef9bb31f31c371272ee9b2860729af2277ab95 Mon Sep 17 00:00:00 2001 From: Marc Dionne Date: Fri, 28 Jan 2011 19:41:32 -0500 Subject: [PATCH 4/8] 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: I38db16f0f62500f46fad9c92d045ccfa6cfe1c38 Signed-off-by: Anders Kaseorg Reviewed-on: http://gerrit.openafs.org/3997 Reviewed-by: Simon Wilkinson Tested-by: BuildBot Reviewed-by: Russ Allbery Reviewed-on: http://gerrit.openafs.org/4040 Reviewed-by: Derrick Brashear Tested-by: Derrick Brashear --- 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 60c47d1..de82283 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 2389389..8352769 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 67ddf91..88e4863 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]) ]) -- 1.7.3.4