From mboxrd@z Thu Jan 1 00:00:00 1970 From: Christoph Hellwig Subject: [PATCH 2/3] fs: add nd_jump_link Date: Mon, 18 Jun 2012 10:47:04 -0400 Message-ID: <20120618144755.549939358@bombadil.infradead.org> References: <20120618144702.856266417@bombadil.infradead.org> Cc: linux-fsdevel@vger.kernel.org To: viro@ZenIV.linux.org.uk Return-path: Received: from 173-166-109-252-newengland.hfc.comcastbusiness.net ([173.166.109.252]:35681 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751555Ab2FROr4 (ORCPT ); Mon, 18 Jun 2012 10:47:56 -0400 Content-Disposition: inline; filename=fs-change-proc-symlinks Sender: linux-fsdevel-owner@vger.kernel.org List-ID: Add a helper that abstracts out the jump to an already parsed struct path from ->follow_link operation from procfs. Not only does this clean up the code by moving the two sides of this game into a single helper, but it also prepares for making struct nameidata private to namei.c Signed-off-by: Christoph Hellwig --- fs/namei.c | 27 +++++++++++++++++---------- fs/proc/base.c | 3 +-- include/linux/namei.h | 2 ++ 3 files changed, 20 insertions(+), 12 deletions(-) Index: linux-2.6/fs/namei.c =================================================================== --- linux-2.6.orig/fs/namei.c 2012-06-18 15:04:54.004355716 +0200 +++ linux-2.6/fs/namei.c 2012-06-18 15:08:29.572361238 +0200 @@ -586,6 +586,21 @@ static inline void path_to_nameidata(con nd->path.dentry = path->dentry; } +/* + * Helper to directly jump to a known parsed path from ->follow_link, + * caller must have taken a reference to path beforehand. + */ +void nd_jump_link(struct nameidata *nd, struct path *path) +{ + path_put(&nd->path); + + nd->path = *path; + nd->inode = nd->path.dentry->d_inode; + nd->flags |= LOOKUP_JUMPED; + + BUG_ON(nd->inode->i_op->follow_link); +} + static inline void put_link(struct nameidata *nd, struct path *link, void *cookie) { struct inode *inode = link->dentry->d_inode; @@ -630,17 +645,9 @@ follow_link(struct path *link, struct na s = nd_get_link(nd); if (s) { error = __vfs_follow_link(nd, s); - } else if (nd->last_type == LAST_BIND) { - nd->flags |= LOOKUP_JUMPED; - nd->inode = nd->path.dentry->d_inode; - if (nd->inode->i_op->follow_link) { - /* stepped on a _really_ weird one */ - path_put(&nd->path); - error = -ELOOP; - } + if (unlikely(error)) + put_link(nd, link, *p); } - if (unlikely(error)) - put_link(nd, link, *p); return error; Index: linux-2.6/include/linux/namei.h =================================================================== --- linux-2.6.orig/include/linux/namei.h 2012-06-18 15:04:54.004355716 +0200 +++ linux-2.6/include/linux/namei.h 2012-06-18 15:05:41.292356924 +0200 @@ -80,6 +80,8 @@ extern int follow_up(struct path *); extern struct dentry *lock_rename(struct dentry *, struct dentry *); extern void unlock_rename(struct dentry *, struct dentry *); +extern void nd_jump_link(struct nameidata *nd, struct path *path); + static inline void nd_set_link(struct nameidata *nd, char *path) { nd->saved_names[nd->depth] = path; Index: linux-2.6/fs/proc/base.c =================================================================== --- linux-2.6.orig/fs/proc/base.c 2012-06-18 15:04:54.004355716 +0200 +++ linux-2.6/fs/proc/base.c 2012-06-18 15:05:41.296356925 +0200 @@ -1438,8 +1438,7 @@ static void *proc_pid_follow_link(struct if (error) goto out; - path_put(&nd->path); - nd->path = path; + nd_jump_link(nd, &path); return NULL; out: return ERR_PTR(error);