diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2011-02-21 21:34:47 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2011-03-14 09:15:23 -0400 |
commit | 52094c8a0610cf57920ad4c6c57470ae2ccbbd25 (patch) | |
tree | 1601d55c395248a429eb1c0fddc1c23094694024 /fs/namei.c | |
parent | c9c6cac0c2bdbda42e7b804838648d0bc60ddb13 (diff) |
take RCU-dependent stuff around exec_permission() into a new helper
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/fs/namei.c b/fs/namei.c index 1d6bc8151553..8c704465f6ce 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -1322,6 +1322,18 @@ fail: | |||
1322 | return PTR_ERR(dentry); | 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 | * Name resolution. | 1338 | * Name resolution. |
1327 | * This is the basic name resolution function, turning a pathname into | 1339 | * This is the basic name resolution function, turning a pathname into |
@@ -1352,17 +1364,8 @@ static int link_path_walk(const char *name, struct nameidata *nd) | |||
1352 | unsigned int c; | 1364 | unsigned int c; |
1353 | 1365 | ||
1354 | nd->flags |= LOOKUP_CONTINUE; | 1366 | nd->flags |= LOOKUP_CONTINUE; |
1355 | if (nd->flags & LOOKUP_RCU) { | 1367 | |
1356 | err = exec_permission(nd->inode, IPERM_FLAG_RCU); | 1368 | err = may_lookup(nd); |
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 | } | ||
1366 | if (err) | 1369 | if (err) |
1367 | break; | 1370 | break; |
1368 | 1371 | ||