diff --git a/acinclude.m4 b/acinclude.m4 index 935fd00086..af56ea4de2 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -837,6 +837,16 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*) LINUX_KBUILD_USES_EXTRA_CFLAGS LINUX_KERNEL_COMPILE_WORKS + dnl Operation signature checks + AC_CHECK_LINUX_OPERATION([inode_operations], [follow_link], [no_nameidata], + [#include ], + [const char *], + [struct dentry *dentry, void **link_data]) + AC_CHECK_LINUX_OPERATION([inode_operations], [put_link], [no_nameidata], + [#include ], + [void], + [struct inode *inode, void *link_data]) + dnl Check for header files AC_CHECK_LINUX_HEADER([config.h]) AC_CHECK_LINUX_HEADER([completion.h]) diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index a878eb4215..3c0cb33e0f 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -1896,14 +1896,22 @@ afs_linux_readlink(struct dentry *dp, char *target, int maxlen) /* afs_linux_follow_link * a file system dependent link following routine. */ +#if defined(HAVE_LINUX_INODE_OPERATIONS_FOLLOW_LINK_NO_NAMEIDATA) +static const char *afs_linux_follow_link(struct dentry *dentry, void **link_data) +#else static int afs_linux_follow_link(struct dentry *dentry, struct nameidata *nd) +#endif { int code; char *name; name = kmalloc(PATH_MAX, GFP_NOFS); if (!name) { +#if defined(HAVE_LINUX_INODE_OPERATIONS_FOLLOW_LINK_NO_NAMEIDATA) + return ERR_PTR(-EIO); +#else return -EIO; +#endif } AFS_GLOCK(); @@ -1911,14 +1919,32 @@ static int afs_linux_follow_link(struct dentry *dentry, struct nameidata *nd) AFS_GUNLOCK(); if (code < 0) { +#if defined(HAVE_LINUX_INODE_OPERATIONS_FOLLOW_LINK_NO_NAMEIDATA) + return ERR_PTR(code); +#else return code; +#endif } name[code] = '\0'; +#if defined(HAVE_LINUX_INODE_OPERATIONS_FOLLOW_LINK_NO_NAMEIDATA) + return *link_data = name; +#else nd_set_link(nd, name); return 0; +#endif } +#if defined(HAVE_LINUX_INODE_OPERATIONS_PUT_LINK_NO_NAMEIDATA) +static void +afs_linux_put_link(struct inode *inode, void *link_data) +{ + char *name = link_data; + + if (name && !IS_ERR(name)) + kfree(name); +} +#else static void afs_linux_put_link(struct dentry *dentry, struct nameidata *nd) { @@ -1927,6 +1953,7 @@ afs_linux_put_link(struct dentry *dentry, struct nameidata *nd) if (name && !IS_ERR(name)) kfree(name); } +#endif /* HAVE_LINUX_INODE_OPERATIONS_PUT_LINK_NO_NAMEIDATA */ #endif /* USABLE_KERNEL_PAGE_SYMLINK_CACHE */