diff options
| -rw-r--r-- | fs/dcache.c | 60 | ||||
| -rw-r--r-- | fs/namei.c | 32 |
2 files changed, 51 insertions, 41 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; |
diff --git a/fs/namei.c b/fs/namei.c index b815a4d2e1d6..11de7c39ff76 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -735,6 +735,11 @@ static int do_lookup(struct nameidata *nd, struct qstr *name, | |||
| 735 | return err; | 735 | return err; |
| 736 | } | 736 | } |
| 737 | 737 | ||
| 738 | /* | ||
| 739 | * Rename seqlock is not required here because in the off chance | ||
| 740 | * of a false negative due to a concurrent rename, we're going to | ||
| 741 | * do the non-racy lookup, below. | ||
| 742 | */ | ||
| 738 | dentry = __d_lookup(nd->path.dentry, name); | 743 | dentry = __d_lookup(nd->path.dentry, name); |
| 739 | if (!dentry) | 744 | if (!dentry) |
| 740 | goto need_lookup; | 745 | goto need_lookup; |
| @@ -754,17 +759,13 @@ need_lookup: | |||
| 754 | mutex_lock(&dir->i_mutex); | 759 | mutex_lock(&dir->i_mutex); |
| 755 | /* | 760 | /* |
| 756 | * First re-do the cached lookup just in case it was created | 761 | * First re-do the cached lookup just in case it was created |
| 757 | * while we waited for the directory semaphore.. | 762 | * while we waited for the directory semaphore, or the first |
| 758 | * | 763 | * lookup failed due to an unrelated rename. |
| 759 | * FIXME! This could use version numbering or similar to | ||
| 760 | * avoid unnecessary cache lookups. | ||
| 761 | * | ||
| 762 | * The "dcache_lock" is purely to protect the RCU list walker | ||
| 763 | * from concurrent renames at this point (we mustn't get false | ||
| 764 | * negatives from the RCU list walk here, unlike the optimistic | ||
| 765 | * fast walk). | ||
| 766 | * | 764 | * |
| 767 | * so doing d_lookup() (with seqlock), instead of lockfree __d_lookup | 765 | * This could use version numbering or similar to avoid unnecessary |
| 766 | * cache lookups, but then we'd have to do the first lookup in the | ||
| 767 | * non-racy way. However in the common case here, everything should | ||
| 768 | * be hot in cache, so would it be a big win? | ||
| 768 | */ | 769 | */ |
| 769 | dentry = d_lookup(parent, name); | 770 | dentry = d_lookup(parent, name); |
| 770 | if (likely(!dentry)) { | 771 | if (likely(!dentry)) { |
| @@ -1136,13 +1137,12 @@ static struct dentry *__lookup_hash(struct qstr *name, | |||
| 1136 | goto out; | 1137 | goto out; |
| 1137 | } | 1138 | } |
| 1138 | 1139 | ||
| 1139 | dentry = __d_lookup(base, name); | 1140 | /* |
| 1140 | 1141 | * Don't bother with __d_lookup: callers are for creat as | |
| 1141 | /* lockess __d_lookup may fail due to concurrent d_move() | 1142 | * well as unlink, so a lot of the time it would cost |
| 1142 | * in some unrelated directory, so try with d_lookup | 1143 | * a double lookup. |
| 1143 | */ | 1144 | */ |
| 1144 | if (!dentry) | 1145 | dentry = d_lookup(base, name); |
| 1145 | dentry = d_lookup(base, name); | ||
| 1146 | 1146 | ||
| 1147 | if (dentry && dentry->d_op && dentry->d_op->d_revalidate) | 1147 | if (dentry && dentry->d_op && dentry->d_op->d_revalidate) |
| 1148 | dentry = do_revalidate(dentry, nd); | 1148 | dentry = do_revalidate(dentry, nd); |
