Commit 52094c8a0610cf57920ad4c6c57470ae2ccbbd25
1 parent
c9c6cac0c2
Exists in
master
and in
20 other branches
take RCU-dependent stuff around exec_permission() into a new helper
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Showing 1 changed file with 14 additions and 11 deletions Side-by-side Diff
fs/namei.c
... | ... | @@ -1322,6 +1322,18 @@ |
1322 | 1322 | return PTR_ERR(dentry); |
1323 | 1323 | } |
1324 | 1324 | |
1325 | +static inline int may_lookup(struct nameidata *nd) | |
1326 | +{ | |
1327 | + if (nd->flags & LOOKUP_RCU) { | |
1328 | + int err = exec_permission(nd->inode, IPERM_FLAG_RCU); | |
1329 | + if (err != -ECHILD) | |
1330 | + return err; | |
1331 | + if (nameidata_drop_rcu(nd)) | |
1332 | + return -ECHILD; | |
1333 | + } | |
1334 | + return exec_permission(nd->inode, 0); | |
1335 | +} | |
1336 | + | |
1325 | 1337 | /* |
1326 | 1338 | * Name resolution. |
1327 | 1339 | * This is the basic name resolution function, turning a pathname into |
... | ... | @@ -1352,17 +1364,8 @@ |
1352 | 1364 | unsigned int c; |
1353 | 1365 | |
1354 | 1366 | nd->flags |= LOOKUP_CONTINUE; |
1355 | - if (nd->flags & LOOKUP_RCU) { | |
1356 | - err = exec_permission(nd->inode, IPERM_FLAG_RCU); | |
1357 | - if (err == -ECHILD) { | |
1358 | - if (nameidata_drop_rcu(nd)) | |
1359 | - return -ECHILD; | |
1360 | - goto exec_again; | |
1361 | - } | |
1362 | - } else { | |
1363 | -exec_again: | |
1364 | - err = exec_permission(nd->inode, 0); | |
1365 | - } | |
1367 | + | |
1368 | + err = may_lookup(nd); | |
1366 | 1369 | if (err) |
1367 | 1370 | break; |
1368 | 1371 |