Skip to content

Commit 58b0afa

Browse files
committed
vfs: link_path_walk: improve may_lookup() code generation
Instead of having separate calls to 'inode_permission()' depending on whether we're in RCU lookup or not, just share the first call. Note that the initial "conditional" on LOOKUP_RCU really turns into just a "convert the LOOKUP_RCU bit in the nameidata into the MAY_NOT_BLOCK bit in the argument", which is just a trivial bitwise and and shift operation. So the initial conditional goes away entirely, and then the likely case is that it will succeed independently of us being in RCU lookup or not, and the possible "we may need to fall out of RCU and redo it all" fixups that are needed afterwards all go in the unlikely path. [ This also marks 'nd' restrict, because that means that the compiler can know that there is no other alias, and can cache the LOOKUP_RCU value over the call to inode_permission(). ] Signed-off-by: Linus Torvalds <[email protected]>
1 parent ba848a7 commit 58b0afa

File tree

1 file changed

+19
-10
lines changed

1 file changed

+19
-10
lines changed

fs/namei.c

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1712,17 +1712,26 @@ static struct dentry *lookup_slow(const struct qstr *name,
17121712
}
17131713

17141714
static inline int may_lookup(struct mnt_idmap *idmap,
1715-
struct nameidata *nd)
1715+
struct nameidata *restrict nd)
17161716
{
1717-
if (nd->flags & LOOKUP_RCU) {
1718-
int err = inode_permission(idmap, nd->inode, MAY_EXEC|MAY_NOT_BLOCK);
1719-
if (!err) // success, keep going
1720-
return 0;
1721-
if (!try_to_unlazy(nd))
1722-
return -ECHILD; // redo it all non-lazy
1723-
if (err != -ECHILD) // hard error
1724-
return err;
1725-
}
1717+
int err, mask;
1718+
1719+
mask = nd->flags & LOOKUP_RCU ? MAY_NOT_BLOCK : 0;
1720+
err = inode_permission(idmap, nd->inode, mask | MAY_EXEC);
1721+
if (likely(!err))
1722+
return 0;
1723+
1724+
// If we failed, and we weren't in LOOKUP_RCU, it's final
1725+
if (!(nd->flags & LOOKUP_RCU))
1726+
return err;
1727+
1728+
// Drop out of RCU mode to make sure it wasn't transient
1729+
if (!try_to_unlazy(nd))
1730+
return -ECHILD; // redo it all non-lazy
1731+
1732+
if (err != -ECHILD) // hard error
1733+
return err;
1734+
17261735
return inode_permission(idmap, nd->inode, MAY_EXEC);
17271736
}
17281737

0 commit comments

Comments
 (0)