diff --git a/acinclude.m4 b/acinclude.m4 index 74fc77619f..f39237b38c 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -901,6 +901,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 481ce87847..6efc0863f6 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -1902,14 +1902,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(); @@ -1917,14 +1925,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) { @@ -1933,6 +1959,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 */