aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dcache.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/dcache.c')
-rw-r--r--fs/dcache.c282
1 files changed, 241 insertions, 41 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index 2355bddad8de..fd4a428998ef 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -478,11 +478,12 @@ static void prune_dcache(int count, struct super_block *sb)
478 up_read(s_umount); 478 up_read(s_umount);
479 } 479 }
480 spin_unlock(&dentry->d_lock); 480 spin_unlock(&dentry->d_lock);
481 /* Cannot remove the first dentry, and it isn't appropriate 481 /*
482 * to move it to the head of the list, so give up, and try 482 * Insert dentry at the head of the list as inserting at the
483 * later 483 * tail leads to a cycle.
484 */ 484 */
485 break; 485 list_add(&dentry->d_lru, &dentry_unused);
486 dentry_stat.nr_unused++;
486 } 487 }
487 spin_unlock(&dcache_lock); 488 spin_unlock(&dcache_lock);
488} 489}
@@ -549,6 +550,142 @@ repeat:
549} 550}
550 551
551/* 552/*
553 * destroy a single subtree of dentries for unmount
554 * - see the comments on shrink_dcache_for_umount() for a description of the
555 * locking
556 */
557static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
558{
559 struct dentry *parent;
560 unsigned detached = 0;
561
562 BUG_ON(!IS_ROOT(dentry));
563
564 /* detach this root from the system */
565 spin_lock(&dcache_lock);
566 if (!list_empty(&dentry->d_lru)) {
567 dentry_stat.nr_unused--;
568 list_del_init(&dentry->d_lru);
569 }
570 __d_drop(dentry);
571 spin_unlock(&dcache_lock);
572
573 for (;;) {
574 /* descend to the first leaf in the current subtree */
575 while (!list_empty(&dentry->d_subdirs)) {
576 struct dentry *loop;
577
578 /* this is a branch with children - detach all of them
579 * from the system in one go */
580 spin_lock(&dcache_lock);
581 list_for_each_entry(loop, &dentry->d_subdirs,
582 d_u.d_child) {
583 if (!list_empty(&loop->d_lru)) {
584 dentry_stat.nr_unused--;
585 list_del_init(&loop->d_lru);
586 }
587
588 __d_drop(loop);
589 cond_resched_lock(&dcache_lock);
590 }
591 spin_unlock(&dcache_lock);
592
593 /* move to the first child */
594 dentry = list_entry(dentry->d_subdirs.next,
595 struct dentry, d_u.d_child);
596 }
597
598 /* consume the dentries from this leaf up through its parents
599 * until we find one with children or run out altogether */
600 do {
601 struct inode *inode;
602
603 if (atomic_read(&dentry->d_count) != 0) {
604 printk(KERN_ERR
605 "BUG: Dentry %p{i=%lx,n=%s}"
606 " still in use (%d)"
607 " [unmount of %s %s]\n",
608 dentry,
609 dentry->d_inode ?
610 dentry->d_inode->i_ino : 0UL,
611 dentry->d_name.name,
612 atomic_read(&dentry->d_count),
613 dentry->d_sb->s_type->name,
614 dentry->d_sb->s_id);
615 BUG();
616 }
617
618 parent = dentry->d_parent;
619 if (parent == dentry)
620 parent = NULL;
621 else
622 atomic_dec(&parent->d_count);
623
624 list_del(&dentry->d_u.d_child);
625 detached++;
626
627 inode = dentry->d_inode;
628 if (inode) {
629 dentry->d_inode = NULL;
630 list_del_init(&dentry->d_alias);
631 if (dentry->d_op && dentry->d_op->d_iput)
632 dentry->d_op->d_iput(dentry, inode);
633 else
634 iput(inode);
635 }
636
637 d_free(dentry);
638
639 /* finished when we fall off the top of the tree,
640 * otherwise we ascend to the parent and move to the
641 * next sibling if there is one */
642 if (!parent)
643 goto out;
644
645 dentry = parent;
646
647 } while (list_empty(&dentry->d_subdirs));
648
649 dentry = list_entry(dentry->d_subdirs.next,
650 struct dentry, d_u.d_child);
651 }
652out:
653 /* several dentries were freed, need to correct nr_dentry */
654 spin_lock(&dcache_lock);
655 dentry_stat.nr_dentry -= detached;
656 spin_unlock(&dcache_lock);
657}
658
659/*
660 * destroy the dentries attached to a superblock on unmounting
661 * - we don't need to use dentry->d_lock, and only need dcache_lock when
662 * removing the dentry from the system lists and hashes because:
663 * - the superblock is detached from all mountings and open files, so the
664 * dentry trees will not be rearranged by the VFS
665 * - s_umount is write-locked, so the memory pressure shrinker will ignore
666 * any dentries belonging to this superblock that it comes across
667 * - the filesystem itself is no longer permitted to rearrange the dentries
668 * in this superblock
669 */
670void shrink_dcache_for_umount(struct super_block *sb)
671{
672 struct dentry *dentry;
673
674 if (down_read_trylock(&sb->s_umount))
675 BUG();
676
677 dentry = sb->s_root;
678 sb->s_root = NULL;
679 atomic_dec(&dentry->d_count);
680 shrink_dcache_for_umount_subtree(dentry);
681
682 while (!hlist_empty(&sb->s_anon)) {
683 dentry = hlist_entry(sb->s_anon.first, struct dentry, d_hash);
684 shrink_dcache_for_umount_subtree(dentry);
685 }
686}
687
688/*
552 * Search for at least 1 mount point in the dentry's subdirs. 689 * Search for at least 1 mount point in the dentry's subdirs.
553 * We descend to the next level whenever the d_subdirs 690 * We descend to the next level whenever the d_subdirs
554 * list is non-empty and continue searching. 691 * list is non-empty and continue searching.
@@ -1339,23 +1476,21 @@ static void switch_names(struct dentry *dentry, struct dentry *target)
1339 * deleted it. 1476 * deleted it.
1340 */ 1477 */
1341 1478
1342/** 1479/*
1343 * d_move - move a dentry 1480 * d_move_locked - move a dentry
1344 * @dentry: entry to move 1481 * @dentry: entry to move
1345 * @target: new dentry 1482 * @target: new dentry
1346 * 1483 *
1347 * Update the dcache to reflect the move of a file name. Negative 1484 * Update the dcache to reflect the move of a file name. Negative
1348 * dcache entries should not be moved in this way. 1485 * dcache entries should not be moved in this way.
1349 */ 1486 */
1350 1487static void d_move_locked(struct dentry * dentry, struct dentry * target)
1351void d_move(struct dentry * dentry, struct dentry * target)
1352{ 1488{
1353 struct hlist_head *list; 1489 struct hlist_head *list;
1354 1490
1355 if (!dentry->d_inode) 1491 if (!dentry->d_inode)
1356 printk(KERN_WARNING "VFS: moving negative dcache entry\n"); 1492 printk(KERN_WARNING "VFS: moving negative dcache entry\n");
1357 1493
1358 spin_lock(&dcache_lock);
1359 write_seqlock(&rename_lock); 1494 write_seqlock(&rename_lock);
1360 /* 1495 /*
1361 * XXXX: do we really need to take target->d_lock? 1496 * XXXX: do we really need to take target->d_lock?
@@ -1406,7 +1541,81 @@ already_unhashed:
1406 fsnotify_d_move(dentry); 1541 fsnotify_d_move(dentry);
1407 spin_unlock(&dentry->d_lock); 1542 spin_unlock(&dentry->d_lock);
1408 write_sequnlock(&rename_lock); 1543 write_sequnlock(&rename_lock);
1544}
1545
1546/**
1547 * d_move - move a dentry
1548 * @dentry: entry to move
1549 * @target: new dentry
1550 *
1551 * Update the dcache to reflect the move of a file name. Negative
1552 * dcache entries should not be moved in this way.
1553 */
1554
1555void d_move(struct dentry * dentry, struct dentry * target)
1556{
1557 spin_lock(&dcache_lock);
1558 d_move_locked(dentry, target);
1559 spin_unlock(&dcache_lock);
1560}
1561
1562/*
1563 * Helper that returns 1 if p1 is a parent of p2, else 0
1564 */
1565static int d_isparent(struct dentry *p1, struct dentry *p2)
1566{
1567 struct dentry *p;
1568
1569 for (p = p2; p->d_parent != p; p = p->d_parent) {
1570 if (p->d_parent == p1)
1571 return 1;
1572 }
1573 return 0;
1574}
1575
1576/*
1577 * This helper attempts to cope with remotely renamed directories
1578 *
1579 * It assumes that the caller is already holding
1580 * dentry->d_parent->d_inode->i_mutex and the dcache_lock
1581 *
1582 * Note: If ever the locking in lock_rename() changes, then please
1583 * remember to update this too...
1584 *
1585 * On return, dcache_lock will have been unlocked.
1586 */
1587static struct dentry *__d_unalias(struct dentry *dentry, struct dentry *alias)
1588{
1589 struct mutex *m1 = NULL, *m2 = NULL;
1590 struct dentry *ret;
1591
1592 /* If alias and dentry share a parent, then no extra locks required */
1593 if (alias->d_parent == dentry->d_parent)
1594 goto out_unalias;
1595
1596 /* Check for loops */
1597 ret = ERR_PTR(-ELOOP);
1598 if (d_isparent(alias, dentry))
1599 goto out_err;
1600
1601 /* See lock_rename() */
1602 ret = ERR_PTR(-EBUSY);
1603 if (!mutex_trylock(&dentry->d_sb->s_vfs_rename_mutex))
1604 goto out_err;
1605 m1 = &dentry->d_sb->s_vfs_rename_mutex;
1606 if (!mutex_trylock(&alias->d_parent->d_inode->i_mutex))
1607 goto out_err;
1608 m2 = &alias->d_parent->d_inode->i_mutex;
1609out_unalias:
1610 d_move_locked(alias, dentry);
1611 ret = alias;
1612out_err:
1409 spin_unlock(&dcache_lock); 1613 spin_unlock(&dcache_lock);
1614 if (m2)
1615 mutex_unlock(m2);
1616 if (m1)
1617 mutex_unlock(m1);
1618 return ret;
1410} 1619}
1411 1620
1412/* 1621/*
@@ -1451,7 +1660,7 @@ static void __d_materialise_dentry(struct dentry *dentry, struct dentry *anon)
1451 */ 1660 */
1452struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode) 1661struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
1453{ 1662{
1454 struct dentry *alias, *actual; 1663 struct dentry *actual;
1455 1664
1456 BUG_ON(!d_unhashed(dentry)); 1665 BUG_ON(!d_unhashed(dentry));
1457 1666
@@ -1463,26 +1672,27 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
1463 goto found_lock; 1672 goto found_lock;
1464 } 1673 }
1465 1674
1466 /* See if a disconnected directory already exists as an anonymous root 1675 if (S_ISDIR(inode->i_mode)) {
1467 * that we should splice into the tree instead */ 1676 struct dentry *alias;
1468 if (S_ISDIR(inode->i_mode) && (alias = __d_find_alias(inode, 1))) { 1677
1469 spin_lock(&alias->d_lock); 1678 /* Does an aliased dentry already exist? */
1470 1679 alias = __d_find_alias(inode, 0);
1471 /* Is this a mountpoint that we could splice into our tree? */ 1680 if (alias) {
1472 if (IS_ROOT(alias)) 1681 actual = alias;
1473 goto connect_mountpoint; 1682 /* Is this an anonymous mountpoint that we could splice
1474 1683 * into our tree? */
1475 if (alias->d_name.len == dentry->d_name.len && 1684 if (IS_ROOT(alias)) {
1476 alias->d_parent == dentry->d_parent && 1685 spin_lock(&alias->d_lock);
1477 memcmp(alias->d_name.name, 1686 __d_materialise_dentry(dentry, alias);
1478 dentry->d_name.name, 1687 __d_drop(alias);
1479 dentry->d_name.len) == 0) 1688 goto found;
1480 goto replace_with_alias; 1689 }
1481 1690 /* Nope, but we must(!) avoid directory aliasing */
1482 spin_unlock(&alias->d_lock); 1691 actual = __d_unalias(dentry, alias);
1483 1692 if (IS_ERR(actual))
1484 /* Doh! Seem to be aliasing directories for some reason... */ 1693 dput(alias);
1485 dput(alias); 1694 goto out_nolock;
1695 }
1486 } 1696 }
1487 1697
1488 /* Add a unique reference */ 1698 /* Add a unique reference */
@@ -1498,7 +1708,7 @@ found:
1498 _d_rehash(actual); 1708 _d_rehash(actual);
1499 spin_unlock(&actual->d_lock); 1709 spin_unlock(&actual->d_lock);
1500 spin_unlock(&dcache_lock); 1710 spin_unlock(&dcache_lock);
1501 1711out_nolock:
1502 if (actual == dentry) { 1712 if (actual == dentry) {
1503 security_d_instantiate(dentry, inode); 1713 security_d_instantiate(dentry, inode);
1504 return NULL; 1714 return NULL;
@@ -1507,16 +1717,6 @@ found:
1507 iput(inode); 1717 iput(inode);
1508 return actual; 1718 return actual;
1509 1719
1510 /* Convert the anonymous/root alias into an ordinary dentry */
1511connect_mountpoint:
1512 __d_materialise_dentry(dentry, alias);
1513
1514 /* Replace the candidate dentry with the alias in the tree */
1515replace_with_alias:
1516 __d_drop(alias);
1517 actual = alias;
1518 goto found;
1519
1520shouldnt_be_hashed: 1720shouldnt_be_hashed:
1521 spin_unlock(&dcache_lock); 1721 spin_unlock(&dcache_lock);
1522 BUG(); 1722 BUG();