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 <buildbot@rampaginggeek.com>
Reviewed-by: Simon Wilkinson <sxw@inf.ed.ac.uk>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
This commit is contained in:
Andrew Deason 2010-12-03 17:20:54 -06:00 committed by Derrick Brashear
parent 64e564b29e
commit 2ce159fbf4

View File

@ -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);
nd_set_link(nd, name);
return 0;
}
out:
osi_Free(name, PATH_MAX);
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,
};