]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
LINUX: Reduce stack depth on recursive symlink res
authorAndrew Deason <adeason@sinenomine.net>
Fri, 3 Dec 2010 23:20:54 +0000 (17:20 -0600)
committerDerrick Brashear <shadow@dementix.org>
Thu, 15 Dec 2011 04:18:44 +0000 (20:18 -0800)
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>
src/afs/LINUX/osi_vnodeops.c

index f877493e5fe8dc0174717f8767d9381096f03ae3..d59d509f3e150ac0d76a2ea4f017bede0e070931 100644 (file)
@@ -1396,16 +1396,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 */
@@ -2462,6 +2467,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,
 };