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.
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>
(cherry picked from commit
2ce159fbf474b96ecd2a4224751d4655230bba51)
Change-Id: Idb91c2bb1a10b60d125dccbc98731ace63d4add8
Reviewed-on: http://gerrit.openafs.org/6269
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@dementix.org>
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 */
#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,
};