Duplicate the revalidation-related parts into if (!dentry) branch. Next step will be to pull them under i_mutex. This and the next 8 commits are more or less a splitup of patch by Miklos; folks, when you are working with something that convoluted, carve your patches up into easily reviewed steps, especially when a lot of codepaths involved are rarely hit...
Unified · Split
| @@ -1194,6 +1194,21 @@ retry: · 1193 unmodified lines | |||
| 1194 | status = 1; | 1194 | status = 1; |
| 1195 | } | 1195 | } |
| 1196 | mutex_unlock(&dir->i_mutex); | 1196 | mutex_unlock(&dir->i_mutex); |
| 1197 | if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE) && need_reval) | ||
| 1198 | status = d_revalidate(dentry, nd); | ||
| 1199 | if (unlikely(status <= 0)) { | ||
| 1200 | if (status < 0) { | ||
| 1201 | dput(dentry); | ||
| 1202 | return status; | ||
| 1203 | } | ||
| 1204 | if (!d_invalidate(dentry)) { | ||
| 1205 | dput(dentry); | ||
| 1206 | dentry = NULL; | ||
| 1207 | need_reval = 1; | ||
| 1208 | goto retry; | ||
| 1209 | } | ||
| 1210 | } | ||
| 1211 | goto done; | ||
| 1197 | } | 1212 | } |
| 1198 | if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE) && need_reval) | 1213 | if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE) && need_reval) |
| 1199 | status = d_revalidate(dentry, nd); | 1214 | status = d_revalidate(dentry, nd); |
| @@ -1209,7 +1224,7 @@ retry: · 9 unmodified lines | |||
| 1209 | goto retry; | 1224 | goto retry; |
| 1210 | } | 1225 | } |
| 1211 | } | 1226 | } |
| 1212 | 1227 | done: | |
| 1213 | path->mnt = mnt; | 1228 | path->mnt = mnt; |
| 1214 | path->dentry = dentry; | 1229 | path->dentry = dentry; |
| 1215 | err = follow_managed(path, nd->flags); | 1230 | err = follow_managed(path, nd->flags); |