aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c76
1 files changed, 66 insertions, 10 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 3d607bd80e09..4a98bf154d88 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -308,6 +308,26 @@ int generic_permission(struct inode *inode, int mask)
308 return -EACCES; 308 return -EACCES;
309} 309}
310 310
311/*
312 * We _really_ want to just do "generic_permission()" without
313 * even looking at the inode->i_op values. So we keep a cache
314 * flag in inode->i_opflags, that says "this has not special
315 * permission function, use the fast case".
316 */
317static inline int do_inode_permission(struct inode *inode, int mask)
318{
319 if (unlikely(!(inode->i_opflags & IOP_FASTPERM))) {
320 if (likely(inode->i_op->permission))
321 return inode->i_op->permission(inode, mask);
322
323 /* This gets set once for the inode lifetime */
324 spin_lock(&inode->i_lock);
325 inode->i_opflags |= IOP_FASTPERM;
326 spin_unlock(&inode->i_lock);
327 }
328 return generic_permission(inode, mask);
329}
330
311/** 331/**
312 * inode_permission - check for access rights to a given inode 332 * inode_permission - check for access rights to a given inode
313 * @inode: inode to check permission on 333 * @inode: inode to check permission on
@@ -322,7 +342,7 @@ int inode_permission(struct inode *inode, int mask)
322{ 342{
323 int retval; 343 int retval;
324 344
325 if (mask & MAY_WRITE) { 345 if (unlikely(mask & MAY_WRITE)) {
326 umode_t mode = inode->i_mode; 346 umode_t mode = inode->i_mode;
327 347
328 /* 348 /*
@@ -339,11 +359,7 @@ int inode_permission(struct inode *inode, int mask)
339 return -EACCES; 359 return -EACCES;
340 } 360 }
341 361
342 if (inode->i_op->permission) 362 retval = do_inode_permission(inode, mask);
343 retval = inode->i_op->permission(inode, mask);
344 else
345 retval = generic_permission(inode, mask);
346
347 if (retval) 363 if (retval)
348 return retval; 364 return retval;
349 365
@@ -1245,6 +1261,26 @@ static void terminate_walk(struct nameidata *nd)
1245 } 1261 }
1246} 1262}
1247 1263
1264/*
1265 * Do we need to follow links? We _really_ want to be able
1266 * to do this check without having to look at inode->i_op,
1267 * so we keep a cache of "no, this doesn't need follow_link"
1268 * for the common case.
1269 */
1270static inline int do_follow_link(struct inode *inode, int follow)
1271{
1272 if (unlikely(!(inode->i_opflags & IOP_NOFOLLOW))) {
1273 if (likely(inode->i_op->follow_link))
1274 return follow;
1275
1276 /* This gets set once for the inode lifetime */
1277 spin_lock(&inode->i_lock);
1278 inode->i_opflags |= IOP_NOFOLLOW;
1279 spin_unlock(&inode->i_lock);
1280 }
1281 return 0;
1282}
1283
1248static inline int walk_component(struct nameidata *nd, struct path *path, 1284static inline int walk_component(struct nameidata *nd, struct path *path,
1249 struct qstr *name, int type, int follow) 1285 struct qstr *name, int type, int follow)
1250{ 1286{
@@ -1267,7 +1303,7 @@ static inline int walk_component(struct nameidata *nd, struct path *path,
1267 terminate_walk(nd); 1303 terminate_walk(nd);
1268 return -ENOENT; 1304 return -ENOENT;
1269 } 1305 }
1270 if (unlikely(inode->i_op->follow_link) && follow) { 1306 if (do_follow_link(inode, follow)) {
1271 if (nd->flags & LOOKUP_RCU) { 1307 if (nd->flags & LOOKUP_RCU) {
1272 if (unlikely(unlazy_walk(nd, path->dentry))) { 1308 if (unlikely(unlazy_walk(nd, path->dentry))) {
1273 terminate_walk(nd); 1309 terminate_walk(nd);
@@ -1320,6 +1356,26 @@ static inline int nested_symlink(struct path *path, struct nameidata *nd)
1320} 1356}
1321 1357
1322/* 1358/*
1359 * We really don't want to look at inode->i_op->lookup
1360 * when we don't have to. So we keep a cache bit in
1361 * the inode ->i_opflags field that says "yes, we can
1362 * do lookup on this inode".
1363 */
1364static inline int can_lookup(struct inode *inode)
1365{
1366 if (likely(inode->i_opflags & IOP_LOOKUP))
1367 return 1;
1368 if (likely(!inode->i_op->lookup))
1369 return 0;
1370
1371 /* We do this once for the lifetime of the inode */
1372 spin_lock(&inode->i_lock);
1373 inode->i_opflags |= IOP_LOOKUP;
1374 spin_unlock(&inode->i_lock);
1375 return 1;
1376}
1377
1378/*
1323 * Name resolution. 1379 * Name resolution.
1324 * This is the basic name resolution function, turning a pathname into 1380 * This is the basic name resolution function, turning a pathname into
1325 * the final dentry. We expect 'base' to be positive and a directory. 1381 * the final dentry. We expect 'base' to be positive and a directory.
@@ -1398,10 +1454,10 @@ static int link_path_walk(const char *name, struct nameidata *nd)
1398 if (err) 1454 if (err)
1399 return err; 1455 return err;
1400 } 1456 }
1457 if (can_lookup(nd->inode))
1458 continue;
1401 err = -ENOTDIR; 1459 err = -ENOTDIR;
1402 if (!nd->inode->i_op->lookup) 1460 break;
1403 break;
1404 continue;
1405 /* here ends the main loop */ 1461 /* here ends the main loop */
1406 1462
1407last_component: 1463last_component: