diff options
| author | Alexander Viro <viro@parcelfarce.linux.theplanet.co.uk> | 2004-07-12 21:16:58 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-07-12 21:16:58 -0700 |
| commit | e4d478f77230c900ca8c0589c34deeea944662ef (patch) | |
| tree | 64ad5c3067fd918a72e9c59ee9e4d94618dd0d3f | |
| parent | 486198fbfff7a410702ef109a0aabe8e7562df5b (diff) | |
[PATCH] __vfs_follow_link() made inline again
__vfs_follow_link() really should be inline; that's a special case since
we are in the middle of recursion and really want to conserve stack
space. Moved before the first use, made inline again.
| -rw-r--r-- | fs/namei.c | 110 |
1 files changed, 55 insertions, 55 deletions
diff --git a/fs/namei.c b/fs/namei.c index bbadcf782e92..3f170ce642e5 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -408,7 +408,61 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, s return result; } -static int __vfs_follow_link(struct nameidata *, const char *); +static int __emul_lookup_dentry(const char *, struct nameidata *); + +/* SMP-safe */ +static inline int +walk_init_root(const char *name, struct nameidata *nd) +{ + read_lock(¤t->fs->lock); + if (current->fs->altroot && !(nd->flags & LOOKUP_NOALT)) { + nd->mnt = mntget(current->fs->altrootmnt); + nd->dentry = dget(current->fs->altroot); + read_unlock(¤t->fs->lock); + if (__emul_lookup_dentry(name,nd)) + return 0; + read_lock(¤t->fs->lock); + } + nd->mnt = mntget(current->fs->rootmnt); + nd->dentry = dget(current->fs->root); + read_unlock(¤t->fs->lock); + return 1; +} + +static inline int __vfs_follow_link(struct nameidata *nd, const char *link) +{ + int res = 0; + char *name; + if (IS_ERR(link)) + goto fail; + + if (*link == '/') { + path_release(nd); + if (!walk_init_root(link, nd)) + /* weird __emul_prefix() stuff did it */ + goto out; + } + res = link_path_walk(link, nd); +out: + if (nd->depth || res || nd->last_type!=LAST_NORM) + return res; + /* + * If it is an iterative symlinks resolution in open_namei() we + * have to copy the last component. And all that crap because of + * bloody create() on broken symlinks. Furrfu... + */ + name = __getname(); + if (unlikely(!name)) { + path_release(nd); + return -ENOMEM; + } + strcpy(name, nd->last.name); + nd->last.name = name; + return 0; +fail: + path_release(nd); + return PTR_ERR(link); +} /* * This limits recursive symlink follows to 8, while @@ -869,25 +923,6 @@ set_it: } } -/* SMP-safe */ -static inline int -walk_init_root(const char *name, struct nameidata *nd) -{ - read_lock(¤t->fs->lock); - if (current->fs->altroot && !(nd->flags & LOOKUP_NOALT)) { - nd->mnt = mntget(current->fs->altrootmnt); - nd->dentry = dget(current->fs->altroot); - read_unlock(¤t->fs->lock); - if (__emul_lookup_dentry(name,nd)) - return 0; - read_lock(¤t->fs->lock); - } - nd->mnt = mntget(current->fs->rootmnt); - nd->dentry = dget(current->fs->root); - read_unlock(¤t->fs->lock); - return 1; -} - int fastcall path_lookup(const char *name, unsigned int flags, struct nameidata *nd) { int retval; @@ -2221,41 +2256,6 @@ int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen) return res; } -static int __vfs_follow_link(struct nameidata *nd, const char *link) -{ - int res = 0; - char *name; - if (IS_ERR(link)) - goto fail; - - if (*link == '/') { - path_release(nd); - if (!walk_init_root(link, nd)) - /* weird __emul_prefix() stuff did it */ - goto out; - } - res = link_path_walk(link, nd); -out: - if (nd->depth || res || nd->last_type!=LAST_NORM) - return res; - /* - * If it is an iterative symlinks resolution in open_namei() we - * have to copy the last component. And all that crap because of - * bloody create() on broken symlinks. Furrfu... - */ - name = __getname(); - if (unlikely(!name)) { - path_release(nd); - return -ENOMEM; - } - strcpy(name, nd->last.name); - nd->last.name = name; - return 0; -fail: - path_release(nd); - return PTR_ERR(link); -} - int vfs_follow_link(struct nameidata *nd, const char *link) { return __vfs_follow_link(nd, link); |
