From 2ce159fbf474b96ecd2a4224751d4655230bba51 Mon Sep 17 00:00:00 2001 From: Andrew Deason Date: Fri, 3 Dec 2010 17:20:54 -0600 Subject: [PATCH] LINUX: Reduce stack depth on recursive symlink res Instead of calling vfs_follow_link inside afs_linux_follow_link ourselves, we can just resolve the next step of the symlink resolution and set the result in nd_set_link(), freeing the string in .put_link(). For kernels without a usable symlink text cache, this reduces call depth when resolving a path containing many symlinks by two frames per layer of indirection, allowing for more deeply-nested symlink paths to be usable. Change-Id: I6886c3b67089c8028fd6ad93ab10eb9173bd6fbe Reviewed-on: http://gerrit.openafs.org/3433 Tested-by: BuildBot Reviewed-by: Simon Wilkinson Reviewed-by: Derrick Brashear --- src/afs/LINUX/osi_vnodeops.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/afs/LINUX/osi_vnodeops.c b/src/afs/LINUX/osi_vnodeops.c index 6b4a7910b..45098b6ec 100644 --- a/src/afs/LINUX/osi_vnodeops.c +++ b/src/afs/LINUX/osi_vnodeops.c @@ -1383,16 +1383,21 @@ static int afs_linux_follow_link(struct dentry *dentry, struct nameidata *nd) AFS_GUNLOCK(); if (code < 0) { - goto out; + return code; } name[code] = '\0'; - code = vfs_follow_link(nd, name); - -out: - osi_Free(name, PATH_MAX); + nd_set_link(nd, name); + return 0; +} - return code; +static int +afs_linux_put_link(struct dentry *dentry, struct nameidata *nd) +{ + char *name = nd_get_link(nd); + if (name && !IS_ERR(name)) { + osi_Free(name, PATH_MAX); + } } #endif /* USABLE_KERNEL_PAGE_SYMLINK_CACHE */ @@ -2426,6 +2431,7 @@ static struct inode_operations afs_symlink_iops = { #else /* !defined(USABLE_KERNEL_PAGE_SYMLINK_CACHE) */ .readlink = afs_linux_readlink, .follow_link = afs_linux_follow_link, + .put_link = afs_linux_put_link, #endif /* USABLE_KERNEL_PAGE_SYMLINK_CACHE */ .setattr = afs_notify_change, }; -- 2.39.5