diff options
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 60 |
1 files changed, 35 insertions, 25 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 4d13bf50b7b1..d56a40b5a577 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -1332,31 +1332,13 @@ EXPORT_SYMBOL(d_add_ci); | |||
1332 | * d_lookup - search for a dentry | 1332 | * d_lookup - search for a dentry |
1333 | * @parent: parent dentry | 1333 | * @parent: parent dentry |
1334 | * @name: qstr of name we wish to find | 1334 | * @name: qstr of name we wish to find |
1335 | * Returns: dentry, or NULL | ||
1335 | * | 1336 | * |
1336 | * Searches the children of the parent dentry for the name in question. If | 1337 | * d_lookup searches the children of the parent dentry for the name in |
1337 | * the dentry is found its reference count is incremented and the dentry | 1338 | * question. If the dentry is found its reference count is incremented and the |
1338 | * is returned. The caller must use dput to free the entry when it has | 1339 | * dentry is returned. The caller must use dput to free the entry when it has |
1339 | * finished using it. %NULL is returned on failure. | 1340 | * finished using it. %NULL is returned if the dentry does not exist. |
1340 | * | ||
1341 | * __d_lookup is dcache_lock free. The hash list is protected using RCU. | ||
1342 | * Memory barriers are used while updating and doing lockless traversal. | ||
1343 | * To avoid races with d_move while rename is happening, d_lock is used. | ||
1344 | * | ||
1345 | * Overflows in memcmp(), while d_move, are avoided by keeping the length | ||
1346 | * and name pointer in one structure pointed by d_qstr. | ||
1347 | * | ||
1348 | * rcu_read_lock() and rcu_read_unlock() are used to disable preemption while | ||
1349 | * lookup is going on. | ||
1350 | * | ||
1351 | * The dentry unused LRU is not updated even if lookup finds the required dentry | ||
1352 | * in there. It is updated in places such as prune_dcache, shrink_dcache_sb, | ||
1353 | * select_parent and __dget_locked. This laziness saves lookup from dcache_lock | ||
1354 | * acquisition. | ||
1355 | * | ||
1356 | * d_lookup() is protected against the concurrent renames in some unrelated | ||
1357 | * directory using the seqlockt_t rename_lock. | ||
1358 | */ | 1341 | */ |
1359 | |||
1360 | struct dentry * d_lookup(struct dentry * parent, struct qstr * name) | 1342 | struct dentry * d_lookup(struct dentry * parent, struct qstr * name) |
1361 | { | 1343 | { |
1362 | struct dentry * dentry = NULL; | 1344 | struct dentry * dentry = NULL; |
@@ -1372,6 +1354,21 @@ struct dentry * d_lookup(struct dentry * parent, struct qstr * name) | |||
1372 | } | 1354 | } |
1373 | EXPORT_SYMBOL(d_lookup); | 1355 | EXPORT_SYMBOL(d_lookup); |
1374 | 1356 | ||
1357 | /* | ||
1358 | * __d_lookup - search for a dentry (racy) | ||
1359 | * @parent: parent dentry | ||
1360 | * @name: qstr of name we wish to find | ||
1361 | * Returns: dentry, or NULL | ||
1362 | * | ||
1363 | * __d_lookup is like d_lookup, however it may (rarely) return a | ||
1364 | * false-negative result due to unrelated rename activity. | ||
1365 | * | ||
1366 | * __d_lookup is slightly faster by avoiding rename_lock read seqlock, | ||
1367 | * however it must be used carefully, eg. with a following d_lookup in | ||
1368 | * the case of failure. | ||
1369 | * | ||
1370 | * __d_lookup callers must be commented. | ||
1371 | */ | ||
1375 | struct dentry * __d_lookup(struct dentry * parent, struct qstr * name) | 1372 | struct dentry * __d_lookup(struct dentry * parent, struct qstr * name) |
1376 | { | 1373 | { |
1377 | unsigned int len = name->len; | 1374 | unsigned int len = name->len; |
@@ -1382,6 +1379,19 @@ struct dentry * __d_lookup(struct dentry * parent, struct qstr * name) | |||
1382 | struct hlist_node *node; | 1379 | struct hlist_node *node; |
1383 | struct dentry *dentry; | 1380 | struct dentry *dentry; |
1384 | 1381 | ||
1382 | /* | ||
1383 | * The hash list is protected using RCU. | ||
1384 | * | ||
1385 | * Take d_lock when comparing a candidate dentry, to avoid races | ||
1386 | * with d_move(). | ||
1387 | * | ||
1388 | * It is possible that concurrent renames can mess up our list | ||
1389 | * walk here and result in missing our dentry, resulting in the | ||
1390 | * false-negative result. d_lookup() protects against concurrent | ||
1391 | * renames using rename_lock seqlock. | ||
1392 | * | ||
1393 | * See Documentation/vfs/dcache-locking.txt for more details. | ||
1394 | */ | ||
1385 | rcu_read_lock(); | 1395 | rcu_read_lock(); |
1386 | 1396 | ||
1387 | hlist_for_each_entry_rcu(dentry, node, head, d_hash) { | 1397 | hlist_for_each_entry_rcu(dentry, node, head, d_hash) { |
@@ -1396,8 +1406,8 @@ struct dentry * __d_lookup(struct dentry * parent, struct qstr * name) | |||
1396 | 1406 | ||
1397 | /* | 1407 | /* |
1398 | * Recheck the dentry after taking the lock - d_move may have | 1408 | * Recheck the dentry after taking the lock - d_move may have |
1399 | * changed things. Don't bother checking the hash because we're | 1409 | * changed things. Don't bother checking the hash because |
1400 | * about to compare the whole name anyway. | 1410 | * we're about to compare the whole name anyway. |
1401 | */ | 1411 | */ |
1402 | if (dentry->d_parent != parent) | 1412 | if (dentry->d_parent != parent) |
1403 | goto next; | 1413 | goto next; |