Commit Graph

774 Commits

Author SHA1 Message Date
Al Viro
e8bb73dfb0 namei: fold put_link() into the failure case of complete_walk()
... and don't open-code unlazy_walk() in there - the only reason
for that is to avoid verfication of cached nd->root, which is
trivially avoided by discarding said cached nd->root first.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:17 -04:00
Al Viro
fab51e8ab2 namei: take the treatment of absolute symlinks to get_link()
rather than letting the callers handle the jump-to-root part of
semantics, do it right in get_link() and return the rest of the
body for the caller to deal with - at that point it's treated
the same way as relative symlinks would be.  And return NULL
when there's no "rest of the body" - those are treated the same
as pure jump symlink would be.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:17 -04:00
Al Viro
4f697a5e17 namei: simpler treatment of symlinks with nothing other that / in the body
Instead of saving name and branching to OK:, where we'll immediately restore
it, and call walk_component() with WALK_PUT|WALK_GET and nd->last_type being
LAST_BIND, which is equivalent to put_link(nd), err = 0, we can just treat
that the same way we'd treat procfs-style "jump" symlinks - do put_link(nd)
and move on.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:16 -04:00
Al Viro
6920a4405e namei: simplify failure exits in get_link()
when cookie is NULL, put_link() is equivalent to path_put(), so
as soon as we'd set last->cookie to NULL, we can bump nd->depth and
let the normal logics in terminate_walk() to take care of cleanups.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:16 -04:00
Al Viro
6e77137b36 don't pass nameidata to ->follow_link()
its only use is getting passed to nd_jump_link(), which can obtain
it from current->nameidata

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:15 -04:00
Al Viro
8402752ecf namei: simplify the callers of follow_managed()
now that it gets nameidata, no reason to have setting LOOKUP_JUMPED on
mountpoint crossing and calling path_put_conditional() on failures
done in every caller.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:15 -04:00
NeilBrown
756daf263e VFS: replace {, total_}link_count in task_struct with pointer to nameidata
task_struct currently contains two ad-hoc members for use by the VFS:
link_count and total_link_count.  These are only interesting to fs/namei.c,
so exposing them explicitly is poor layering.  Incidentally, link_count
isn't used anymore, so it can just die.

This patches replaces those with a single pointer to 'struct nameidata'.
This structure represents the current filename lookup of which
there can only be one per process, and is a natural place to
store total_link_count.

This will allow the current "nameidata" argument to all
follow_link operations to be removed as current->nameidata
can be used instead in the _very_ few instances that care about
it at all.

As there are occasional circumstances where pathname lookup can
recurse, such as through kern_path_locked, we always save and old
current->nameidata (if there is one) when setting a new value, and
make sure any active link_counts are preserved.

follow_mount and follow_automount now get a 'struct nameidata *'
rather than 'int flags' so that they can directly access
total_link_count, rather than going through 'current'.

Suggested-by: Al Viro <viro@ZenIV.linux.org.uk>
Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:14 -04:00
Al Viro
626de99676 namei: move link count check and stack allocation into pick_link()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:13 -04:00
Al Viro
d63ff28f0f namei: make should_follow_link() store the link in nd->link
... if it decides to follow, that is.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:13 -04:00
Al Viro
4693a547cd namei: new calling conventions for walk_component()
instead of a single flag (!= 0 => we want to follow symlinks) pass
two bits - WALK_GET (want to follow symlinks) and WALK_PUT (put_link()
once we are done looking at the name).  The latter matters only for
success exits - on failure the caller will discard everything anyway.

Suggestions for better variant are welcome; what this thing aims for
is making sure that pending put_link() is done *before* walk_component()
decides to pick a symlink up, rather than between picking it up and
acting upon it.  See the next commit for payoff.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:12 -04:00
Al Viro
8620c238ed link_path_walk: move the OK: inside the loop
fewer labels that way; in particular, resuming after the end of
nested symlink is straight-line.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:12 -04:00
Al Viro
1543972678 namei: have terminate_walk() do put_link() on everything left
All callers of terminate_walk() are followed by more or less
open-coded eqiuvalent of "do put_link() on everything left
in nd->stack".  Better done in terminate_walk() itself, and
when we go for RCU symlink traversal we'll have to do it
there anyway.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:11 -04:00
Al Viro
191d7f73e2 namei: take put_link() into {lookup,mountpoint,do}_last()
rationale: we'll need to have terminate_walk() do put_link() on
everything, which will mean that in some cases ..._last() will do
put_link() anyway.  Easier to have them do it in all cases.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:11 -04:00
Al Viro
1bc4b813e8 namei: lift (open-coded) terminate_walk() into callers of get_link()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:10 -04:00
Al Viro
f0a9ba7021 lift terminate_walk() into callers of walk_component()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:10 -04:00
Al Viro
70291aecc6 namei: lift (open-coded) terminate_walk() in follow_dotdot_rcu() into callers
follow_dotdot_rcu() does an equivalent of terminate_walk() on failure;
shifting it into callers makes for simpler rules and those callers
already have terminate_walk() on other failure exits.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:09 -04:00
Al Viro
e269f2a73f namei: we never need more than MAXSYMLINKS entries in nd->stack
The only reason why we needed one more was that purely nested
MAXSYMLINKS symlinks could lead to path_init() using that many
entries in addition to nd->stack[0] which it left unused.

That can't happen now - path_init() starts with entry 0 (and
trailing_symlink() is called only when we'd already encountered
one symlink, so no more than MAXSYMLINKS-1 are left).

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:08 -04:00
Al Viro
8eff733a45 link_path_walk: end of nd->depth massage
get rid of orig_depth - we only use it on error exit to tell whether
to stop doing put_link() when depth reaches 0 (call from path_init())
or when it reaches 1 (call from trailing_symlink()).  However, in
the latter case the caller would immediately follow with one more
put_link().  Just keep doing it until the depth reaches zero (and
simplify trailing_symlink() as the result).

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:08 -04:00
Al Viro
939724df56 link_path_walk: nd->depth massage, part 10
Get rid of orig_depth checks in OK: logics.  If nd->depth is
zero, we had been called from path_init() and we are done.
If it is greater than 1, we are not done, whether we'd been
called from path_init() or trailing_symlink().  And in
case when it's 1, we might have been called from path_init()
and reached the end of nested symlink (in which case
nd->stack[0].name will point to the rest of pathname and
we are not done) or from trailing_symlink(), in which case
we are done.

Just have trailing_symlink() leave NULL in nd->stack[0].name
and use that to discriminate between those cases.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:06 -04:00
Al Viro
dc7af8dc05 link_path_walk: nd->depth massage, part 9
Make link_path_walk() work with any value of nd->depth on entry -
memorize it and use it in tests instead of comparing with 1.
Don't bother with increment/decrement in path_init().

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:06 -04:00
Al Viro
21c3003d36 put_link: nd->depth massage, part 8
all calls are preceded by decrement of nd->depth; move it into
put_link() itself.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:05 -04:00
Al Viro
9ea57b72bf trailing_symlink: nd->depth massage, part 7
move decrement of nd->depth on successful returns into the callers.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:05 -04:00
Al Viro
0fd889d59e get_link: nd->depth massage, part 6
make get_link() increment nd->depth on successful exit

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:04 -04:00
Al Viro
f7df08ee05 trailing_symlink: nd->depth massage, part 5
move increment of ->depth to the point where we'd discovered
that get_link() has not returned an error, adjust exits
accordingly.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:04 -04:00
Al Viro
ef1a3e7b96 link_path_walk: nd->depth massage, part 4
lift increment/decrement into link_path_walk() callers.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:03 -04:00
Al Viro
da4e0be04d link_path_walk: nd->depth massage, part 3
remove decrement/increment surrounding nd_alloc_stack(), adjust the
test in it.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:03 -04:00
Al Viro
fd4620bbdf link_path_walk: nd->depth massage, part 2
collapse adjacent increment/decrement pairs.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:02 -04:00
Al Viro
071bf50137 link_path_walk: nd->depth massage, part 1
nd->stack[0] is unused until the handling of trailing symlinks and
we want to get rid of that.  Having fucked that transformation up
several times, I went for bloody pedantic series of provably equivalent
transformations.  Sorry.

Step 1: keep nd->depth higher by one in link_path_walk() - increment upon
entry, decrement on exits, adjust the arithmetics inside and surround the
calls of functions that care about nd->depth value (nd_alloc_stack(),
get_link(), put_link()) with decrement/increment pairs.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:02 -04:00
Al Viro
894bc8c466 namei: remove restrictions on nesting depth
The only restriction is that on the total amount of symlinks
crossed; how they are nested does not matter

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:01 -04:00
Al Viro
3b2e7f7539 namei: trim the arguments of get_link()
same story as the previous commit

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:01 -04:00
Al Viro
b9ff44293c namei: trim redundant arguments of fs/namei.c:put_link()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:00 -04:00
Al Viro
1d8e03d359 namei: trim redundant arguments of trailing_symlink()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:20:00 -04:00
Al Viro
697fc6ca66 namei: move link/cookie pairs into nameidata
Array of MAX_NESTED_LINKS + 1 elements put into nameidata;
what used to be a local array in link_path_walk() occupies
entries 1 .. MAX_NESTED_LINKS in it, link and cookie from
the trailing symlink handling loops - entry 0.

This is _not_ the final arrangement; just an easily verified
incremental step.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:19:59 -04:00
Al Viro
9e18f10a30 link_path_walk: cleanup - turn goto start; into continue;
Deal with skipping leading slashes before what used to be the
recursive call.  That way we can get rid of that goto completely.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:19:59 -04:00
Al Viro
07681481b8 link_path_walk: split "return from recursive call" path
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:19:58 -04:00
Al Viro
32cd74685c link_path_walk: kill the recursion
absolutely straightforward now - the only variables we need to preserve
across the recursive call are name, link and cookie, and recursion depth
is limited (and can is equal to nd->depth).  So arrange an array of
triples to hold instances of those and be done with that.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:19:58 -04:00
Al Viro
bdf6cbf179 link_path_walk: final preparations to killing recursion
reduce the number of returns in there - turn all places
where it returns zero into goto OK and places where it
returns non-zero into goto Err.  The only non-trivial
detail is that all breaks in the loop are guaranteed
to be with non-zero err.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:19:57 -04:00
Al Viro
bb8603f8e1 link_path_walk: get rid of duplication
What we do after the second walk_component() + put_link() + depth
decrement in there is exactly equivalent to what's done right
after the first walk_component().  Easy to verify and not at all
surprising, seeing that there we have just walked the last
component of nested symlink.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:19:57 -04:00
Al Viro
48c8b0c571 link_path_walk: massage a bit more
Pull the block after the if-else in the end of what used to be do-while
body into all branches there.  We are almost done with the massage...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:19:56 -04:00
Al Viro
d40bcc09ab link_path_walk: turn inner loop into explicit goto
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:19:56 -04:00
Al Viro
12b0957800 link_path_walk: don't bother with walk_component() after jumping link
... it does nothing if nd->last_type is LAST_BIND.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:19:55 -04:00
Al Viro
b0c24c3bdf link_path_walk: handle get_link() returning ERR_PTR() immediately
If we get ERR_PTR() from get_link(), we are guaranteed to get err != 0
when we break out of do-while, so we are going to hit if (err) return err;
shortly after it.  Pull that into the if (IS_ERR(s)) body.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:19:55 -04:00
Al Viro
95fa25d9f2 namei: rename follow_link to trailing_symlink, move it down
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:19:54 -04:00
Al Viro
21fef2176e namei: move the calls of may_follow_link() into follow_link()
All remaining callers of the former are preceded by the latter

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:19:53 -04:00
Al Viro
172a39a059 namei: expand the call of follow_link() in link_path_walk()
... and strip __always_inline from follow_link() - remaining callers
don't need that.

Now link_path_walk() recursion is a direct one.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:19:53 -04:00
Al Viro
5a460275ef namei: expand nested_symlink() in its only caller
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:19:52 -04:00
Al Viro
896475d5bd do_last: move path there from caller's stack frame
We used to need it to feed to follow_link().  No more...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:19:52 -04:00
Al Viro
caa8563443 namei: introduce nameidata->link
shares space with nameidata->next, walk_component() et.al. store
the struct path of symlink instead of returning it into a variable
passed by caller.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:19:51 -04:00
Al Viro
d4dee48bad namei: don't bother with ->follow_link() if ->i_link is set
with new calling conventions it's trivial

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Conflicts:
	fs/namei.c
2015-05-10 22:19:51 -04:00
Al Viro
0a959df54b namei.c: separate the parts of follow_link() that find the link body
Split a piece of fs/namei.c:follow_link() that does obtaining the link
body into a separate function.  follow_link() itself is converted to
calling get_link() and then doing the body traversal (if any).

The next step will expand follow_link() call in link_path_walk()
and this helps to keep the size down...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
2015-05-10 22:19:50 -04:00