Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

fs: make sure to fail try_to_unlazy() and try_to_unlazy() for LOOKUP_CACHED

Otherwise the slowpath can be taken by the caller, defeating the flag.

This regressed after calls to legitimize_links() started being
conditionally elided and stems from the routine always failing
after seeing the flag, regardless if there were any links.

In order to address both the bug and the weird semantics make it illegal
to call legitimize_links() with LOOKUP_CACHED and handle the problem at
the two callsites.

Fixes: 7c179096e77eca21 ("fs: add predicts based on nd->depth")
Reported-by: Chris Mason <clm@meta.com>
Signed-off-by: Mateusz Guzik <mjguzik@gmail.com>
Link: https://patch.msgid.link/20251220054023.142134-1-mjguzik@gmail.com
Signed-off-by: Christian Brauner <brauner@kernel.org>

authored by

Mateusz Guzik and committed by
Christian Brauner
46af9ae1 570ad253

+13 -5
+13 -5
fs/namei.c
··· 830 830 static bool legitimize_links(struct nameidata *nd) 831 831 { 832 832 int i; 833 - if (unlikely(nd->flags & LOOKUP_CACHED)) { 834 - drop_links(nd); 835 - nd->depth = 0; 836 - return false; 837 - } 833 + 834 + VFS_BUG_ON(nd->flags & LOOKUP_CACHED); 835 + 838 836 for (i = 0; i < nd->depth; i++) { 839 837 struct saved *last = nd->stack + i; 840 838 if (unlikely(!legitimize_path(nd, &last->link, last->seq))) { ··· 881 883 882 884 BUG_ON(!(nd->flags & LOOKUP_RCU)); 883 885 886 + if (unlikely(nd->flags & LOOKUP_CACHED)) { 887 + drop_links(nd); 888 + nd->depth = 0; 889 + goto out1; 890 + } 884 891 if (unlikely(nd->depth && !legitimize_links(nd))) 885 892 goto out1; 886 893 if (unlikely(!legitimize_path(nd, &nd->path, nd->seq))) ··· 921 918 int res; 922 919 BUG_ON(!(nd->flags & LOOKUP_RCU)); 923 920 921 + if (unlikely(nd->flags & LOOKUP_CACHED)) { 922 + drop_links(nd); 923 + nd->depth = 0; 924 + goto out2; 925 + } 924 926 if (unlikely(nd->depth && !legitimize_links(nd))) 925 927 goto out2; 926 928 res = __legitimize_mnt(nd->path.mnt, nd->m_seq);