Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6:
get rid of nameidata_dentry_drop_rcu() calling nameidata_drop_rcu()
drop out of RCU in return_reval
split do_revalidate() into RCU and non-RCU cases
in do_lookup() split RCU and non-RCU cases of need_revalidate
nothing in do_follow_link() is going to see RCU

+57 -65
+57 -65
fs/namei.c
··· 455 455 struct fs_struct *fs = current->fs; 456 456 struct dentry *parent = nd->path.dentry; 457 457 458 - /* 459 - * It can be possible to revalidate the dentry that we started 460 - * the path walk with. force_reval_path may also revalidate the 461 - * dentry already committed to the nameidata. 462 - */ 463 - if (unlikely(parent == dentry)) 464 - return nameidata_drop_rcu(nd); 465 - 466 458 BUG_ON(!(nd->flags & LOOKUP_RCU)); 467 459 if (nd->root.mnt) { 468 460 spin_lock(&fs->lock); ··· 563 571 } 564 572 } 565 573 566 - /* 567 - * Call d_revalidate and handle filesystems that request rcu-walk 568 - * to be dropped. This may be called and return in rcu-walk mode, 569 - * regardless of success or error. If -ECHILD is returned, the caller 570 - * must return -ECHILD back up the path walk stack so path walk may 571 - * be restarted in ref-walk mode. 572 - */ 573 - static int d_revalidate(struct dentry *dentry, struct nameidata *nd) 574 + static inline int d_revalidate(struct dentry *dentry, struct nameidata *nd) 574 575 { 575 - int status; 576 - 577 - status = dentry->d_op->d_revalidate(dentry, nd); 578 - if (status == -ECHILD) { 579 - if (nameidata_dentry_drop_rcu(nd, dentry)) 580 - return status; 581 - status = dentry->d_op->d_revalidate(dentry, nd); 582 - } 583 - 584 - return status; 576 + return dentry->d_op->d_revalidate(dentry, nd); 585 577 } 586 578 587 - static inline struct dentry * 579 + static struct dentry * 588 580 do_revalidate(struct dentry *dentry, struct nameidata *nd) 589 581 { 590 - int status; 591 - 592 - status = d_revalidate(dentry, nd); 582 + int status = d_revalidate(dentry, nd); 593 583 if (unlikely(status <= 0)) { 594 584 /* 595 585 * The dentry failed validation. ··· 580 606 * to return a fail status. 581 607 */ 582 608 if (status < 0) { 583 - /* If we're in rcu-walk, we don't have a ref */ 584 - if (!(nd->flags & LOOKUP_RCU)) 585 - dput(dentry); 609 + dput(dentry); 586 610 dentry = ERR_PTR(status); 587 - 588 - } else { 589 - /* Don't d_invalidate in rcu-walk mode */ 590 - if (nameidata_dentry_drop_rcu_maybe(nd, dentry)) 591 - return ERR_PTR(-ECHILD); 592 - if (!d_invalidate(dentry)) { 593 - dput(dentry); 594 - dentry = NULL; 595 - } 611 + } else if (!d_invalidate(dentry)) { 612 + dput(dentry); 613 + dentry = NULL; 596 614 } 615 + } 616 + return dentry; 617 + } 618 + 619 + static inline struct dentry * 620 + do_revalidate_rcu(struct dentry *dentry, struct nameidata *nd) 621 + { 622 + int status = d_revalidate(dentry, nd); 623 + if (likely(status > 0)) 624 + return dentry; 625 + if (status == -ECHILD) { 626 + if (nameidata_dentry_drop_rcu(nd, dentry)) 627 + return ERR_PTR(-ECHILD); 628 + return do_revalidate(dentry, nd); 629 + } 630 + if (status < 0) 631 + return ERR_PTR(status); 632 + /* Don't d_invalidate in rcu-walk mode */ 633 + if (nameidata_dentry_drop_rcu(nd, dentry)) 634 + return ERR_PTR(-ECHILD); 635 + if (!d_invalidate(dentry)) { 636 + dput(dentry); 637 + dentry = NULL; 597 638 } 598 639 return dentry; 599 640 } ··· 657 668 return 0; 658 669 659 670 if (!status) { 660 - /* Don't d_invalidate in rcu-walk mode */ 661 - if (nameidata_drop_rcu(nd)) 662 - return -ECHILD; 663 671 d_invalidate(dentry); 664 672 status = -ESTALE; 665 673 } ··· 763 777 int error; 764 778 struct dentry *dentry = link->dentry; 765 779 780 + BUG_ON(nd->flags & LOOKUP_RCU); 781 + 766 782 touch_atime(link->mnt, dentry); 767 783 nd_set_link(nd, NULL); 768 784 ··· 799 811 { 800 812 void *cookie; 801 813 int err = -ELOOP; 814 + 815 + /* We drop rcu-walk here */ 816 + if (nameidata_dentry_drop_rcu_maybe(nd, path->dentry)) 817 + return -ECHILD; 818 + 802 819 if (current->link_count >= MAX_NESTED_LINKS) 803 820 goto loop; 804 821 if (current->total_link_count >= 40) ··· 1248 1255 return -ECHILD; 1249 1256 1250 1257 nd->seq = seq; 1251 - if (dentry->d_flags & DCACHE_OP_REVALIDATE) 1252 - goto need_revalidate; 1253 - done2: 1258 + if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE)) { 1259 + dentry = do_revalidate_rcu(dentry, nd); 1260 + if (!dentry) 1261 + goto need_lookup; 1262 + if (IS_ERR(dentry)) 1263 + goto fail; 1264 + if (!(nd->flags & LOOKUP_RCU)) 1265 + goto done; 1266 + } 1254 1267 path->mnt = mnt; 1255 1268 path->dentry = dentry; 1256 1269 if (likely(__follow_mount_rcu(nd, path, inode, false))) ··· 1269 1270 if (!dentry) 1270 1271 goto need_lookup; 1271 1272 found: 1272 - if (dentry->d_flags & DCACHE_OP_REVALIDATE) 1273 - goto need_revalidate; 1273 + if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE)) { 1274 + dentry = do_revalidate(dentry, nd); 1275 + if (!dentry) 1276 + goto need_lookup; 1277 + if (IS_ERR(dentry)) 1278 + goto fail; 1279 + } 1274 1280 done: 1275 1281 path->mnt = mnt; 1276 1282 path->dentry = dentry; ··· 1316 1312 */ 1317 1313 mutex_unlock(&dir->i_mutex); 1318 1314 goto found; 1319 - 1320 - need_revalidate: 1321 - dentry = do_revalidate(dentry, nd); 1322 - if (!dentry) 1323 - goto need_lookup; 1324 - if (IS_ERR(dentry)) 1325 - goto fail; 1326 - if (nd->flags & LOOKUP_RCU) 1327 - goto done2; 1328 - goto done; 1329 1315 1330 1316 fail: 1331 1317 return PTR_ERR(dentry); ··· 1413 1419 goto out_dput; 1414 1420 1415 1421 if (inode->i_op->follow_link) { 1416 - /* We commonly drop rcu-walk here */ 1417 - if (nameidata_dentry_drop_rcu_maybe(nd, next.dentry)) 1418 - return -ECHILD; 1419 1422 BUG_ON(inode != next.dentry->d_inode); 1420 1423 err = do_follow_link(&next, nd); 1421 1424 if (err) ··· 1458 1467 break; 1459 1468 if (inode && unlikely(inode->i_op->follow_link) && 1460 1469 (lookup_flags & LOOKUP_FOLLOW)) { 1461 - if (nameidata_dentry_drop_rcu_maybe(nd, next.dentry)) 1462 - return -ECHILD; 1463 1470 BUG_ON(inode != next.dentry->d_inode); 1464 1471 err = do_follow_link(&next, nd); 1465 1472 if (err) ··· 1493 1504 * We may need to check the cached dentry for staleness. 1494 1505 */ 1495 1506 if (need_reval_dot(nd->path.dentry)) { 1507 + if (nameidata_drop_rcu_last_maybe(nd)) 1508 + return -ECHILD; 1496 1509 /* Note: we do not d_invalidate() */ 1497 1510 err = d_revalidate(nd->path.dentry, nd); 1498 1511 if (!err) 1499 1512 err = -ESTALE; 1500 1513 if (err < 0) 1501 1514 break; 1515 + return 0; 1502 1516 } 1503 1517 return_base: 1504 1518 if (nameidata_drop_rcu_last_maybe(nd))