Loading fs/namei.c +14 −14 Original line number Diff line number Diff line Loading @@ -705,19 +705,19 @@ static bool try_to_unlazy(struct nameidata *nd) } /** * unlazy_child - try to switch to ref-walk mode. * try_to_unlazy_next - try to switch to ref-walk mode. * @nd: nameidata pathwalk data * @dentry: child of nd->path.dentry * @seq: seq number to check dentry against * Returns: 0 on success, -ECHILD on failure * @dentry: next dentry to step into * @seq: seq number to check @dentry against * Returns: true on success, false on failure * * unlazy_child attempts to legitimize the current nd->path, nd->root and dentry * for ref-walk mode. @dentry must be a path found by a do_lookup call on * @nd. Must be called from rcu-walk context. * Nothing should touch nameidata between unlazy_child() failure and * Similar to to try_to_unlazy(), but here we have the next dentry already * picked by rcu-walk and want to legitimize that in addition to the current * nd->path and nd->root for ref-walk mode. Must be called from rcu-walk context. * Nothing should touch nameidata between try_to_unlazy_next() failure and * terminate_walk(). */ static int unlazy_child(struct nameidata *nd, struct dentry *dentry, unsigned seq) static bool try_to_unlazy_next(struct nameidata *nd, struct dentry *dentry, unsigned seq) { BUG_ON(!(nd->flags & LOOKUP_RCU)); Loading Loading @@ -747,7 +747,7 @@ static int unlazy_child(struct nameidata *nd, struct dentry *dentry, unsigned se if (unlikely(!legitimize_root(nd))) goto out_dput; rcu_read_unlock(); return 0; return true; out2: nd->path.mnt = NULL; Loading @@ -755,11 +755,11 @@ static int unlazy_child(struct nameidata *nd, struct dentry *dentry, unsigned se nd->path.dentry = NULL; out: rcu_read_unlock(); return -ECHILD; return false; out_dput: rcu_read_unlock(); dput(dentry); return -ECHILD; return false; } static inline int d_revalidate(struct dentry *dentry, unsigned int flags) Loading Loading @@ -1372,7 +1372,7 @@ static inline int handle_mounts(struct nameidata *nd, struct dentry *dentry, return -ENOENT; if (likely(__follow_mount_rcu(nd, path, inode, seqp))) return 0; if (unlazy_child(nd, dentry, seq)) if (!try_to_unlazy_next(nd, dentry, seq)) return -ECHILD; // *path might've been clobbered by __follow_mount_rcu() path->mnt = nd->path.mnt; Loading Loading @@ -1493,7 +1493,7 @@ static struct dentry *lookup_fast(struct nameidata *nd, status = d_revalidate(dentry, nd->flags); if (likely(status > 0)) return dentry; if (unlazy_child(nd, dentry, seq)) if (!try_to_unlazy_next(nd, dentry, seq)) return ERR_PTR(-ECHILD); if (status == -ECHILD) /* we'd been told to redo it in non-rcu mode */ Loading Loading
fs/namei.c +14 −14 Original line number Diff line number Diff line Loading @@ -705,19 +705,19 @@ static bool try_to_unlazy(struct nameidata *nd) } /** * unlazy_child - try to switch to ref-walk mode. * try_to_unlazy_next - try to switch to ref-walk mode. * @nd: nameidata pathwalk data * @dentry: child of nd->path.dentry * @seq: seq number to check dentry against * Returns: 0 on success, -ECHILD on failure * @dentry: next dentry to step into * @seq: seq number to check @dentry against * Returns: true on success, false on failure * * unlazy_child attempts to legitimize the current nd->path, nd->root and dentry * for ref-walk mode. @dentry must be a path found by a do_lookup call on * @nd. Must be called from rcu-walk context. * Nothing should touch nameidata between unlazy_child() failure and * Similar to to try_to_unlazy(), but here we have the next dentry already * picked by rcu-walk and want to legitimize that in addition to the current * nd->path and nd->root for ref-walk mode. Must be called from rcu-walk context. * Nothing should touch nameidata between try_to_unlazy_next() failure and * terminate_walk(). */ static int unlazy_child(struct nameidata *nd, struct dentry *dentry, unsigned seq) static bool try_to_unlazy_next(struct nameidata *nd, struct dentry *dentry, unsigned seq) { BUG_ON(!(nd->flags & LOOKUP_RCU)); Loading Loading @@ -747,7 +747,7 @@ static int unlazy_child(struct nameidata *nd, struct dentry *dentry, unsigned se if (unlikely(!legitimize_root(nd))) goto out_dput; rcu_read_unlock(); return 0; return true; out2: nd->path.mnt = NULL; Loading @@ -755,11 +755,11 @@ static int unlazy_child(struct nameidata *nd, struct dentry *dentry, unsigned se nd->path.dentry = NULL; out: rcu_read_unlock(); return -ECHILD; return false; out_dput: rcu_read_unlock(); dput(dentry); return -ECHILD; return false; } static inline int d_revalidate(struct dentry *dentry, unsigned int flags) Loading Loading @@ -1372,7 +1372,7 @@ static inline int handle_mounts(struct nameidata *nd, struct dentry *dentry, return -ENOENT; if (likely(__follow_mount_rcu(nd, path, inode, seqp))) return 0; if (unlazy_child(nd, dentry, seq)) if (!try_to_unlazy_next(nd, dentry, seq)) return -ECHILD; // *path might've been clobbered by __follow_mount_rcu() path->mnt = nd->path.mnt; Loading Loading @@ -1493,7 +1493,7 @@ static struct dentry *lookup_fast(struct nameidata *nd, status = d_revalidate(dentry, nd->flags); if (likely(status > 0)) return dentry; if (unlazy_child(nd, dentry, seq)) if (!try_to_unlazy_next(nd, dentry, seq)) return ERR_PTR(-ECHILD); if (status == -ECHILD) /* we'd been told to redo it in non-rcu mode */ Loading