diff options
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 68 |
1 files changed, 34 insertions, 34 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 87bdb5329c3c..b949af850cd6 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -229,7 +229,7 @@ static void __d_free(struct rcu_head *head) | |||
229 | */ | 229 | */ |
230 | static void d_free(struct dentry *dentry) | 230 | static void d_free(struct dentry *dentry) |
231 | { | 231 | { |
232 | BUG_ON(dentry->d_count); | 232 | BUG_ON(dentry->d_lockref.count); |
233 | this_cpu_dec(nr_dentry); | 233 | this_cpu_dec(nr_dentry); |
234 | if (dentry->d_op && dentry->d_op->d_release) | 234 | if (dentry->d_op && dentry->d_op->d_release) |
235 | dentry->d_op->d_release(dentry); | 235 | dentry->d_op->d_release(dentry); |
@@ -467,7 +467,7 @@ relock: | |||
467 | } | 467 | } |
468 | 468 | ||
469 | if (ref) | 469 | if (ref) |
470 | dentry->d_count--; | 470 | dentry->d_lockref.count--; |
471 | /* | 471 | /* |
472 | * inform the fs via d_prune that this dentry is about to be | 472 | * inform the fs via d_prune that this dentry is about to be |
473 | * unhashed and destroyed. | 473 | * unhashed and destroyed. |
@@ -513,15 +513,10 @@ void dput(struct dentry *dentry) | |||
513 | return; | 513 | return; |
514 | 514 | ||
515 | repeat: | 515 | repeat: |
516 | if (dentry->d_count == 1) | 516 | if (dentry->d_lockref.count == 1) |
517 | might_sleep(); | 517 | might_sleep(); |
518 | spin_lock(&dentry->d_lock); | 518 | if (lockref_put_or_lock(&dentry->d_lockref)) |
519 | BUG_ON(!dentry->d_count); | ||
520 | if (dentry->d_count > 1) { | ||
521 | dentry->d_count--; | ||
522 | spin_unlock(&dentry->d_lock); | ||
523 | return; | 519 | return; |
524 | } | ||
525 | 520 | ||
526 | if (dentry->d_flags & DCACHE_OP_DELETE) { | 521 | if (dentry->d_flags & DCACHE_OP_DELETE) { |
527 | if (dentry->d_op->d_delete(dentry)) | 522 | if (dentry->d_op->d_delete(dentry)) |
@@ -535,7 +530,7 @@ repeat: | |||
535 | dentry->d_flags |= DCACHE_REFERENCED; | 530 | dentry->d_flags |= DCACHE_REFERENCED; |
536 | dentry_lru_add(dentry); | 531 | dentry_lru_add(dentry); |
537 | 532 | ||
538 | dentry->d_count--; | 533 | dentry->d_lockref.count--; |
539 | spin_unlock(&dentry->d_lock); | 534 | spin_unlock(&dentry->d_lock); |
540 | return; | 535 | return; |
541 | 536 | ||
@@ -590,7 +585,7 @@ int d_invalidate(struct dentry * dentry) | |||
590 | * We also need to leave mountpoints alone, | 585 | * We also need to leave mountpoints alone, |
591 | * directory or not. | 586 | * directory or not. |
592 | */ | 587 | */ |
593 | if (dentry->d_count > 1 && dentry->d_inode) { | 588 | if (dentry->d_lockref.count > 1 && dentry->d_inode) { |
594 | if (S_ISDIR(dentry->d_inode->i_mode) || d_mountpoint(dentry)) { | 589 | if (S_ISDIR(dentry->d_inode->i_mode) || d_mountpoint(dentry)) { |
595 | spin_unlock(&dentry->d_lock); | 590 | spin_unlock(&dentry->d_lock); |
596 | return -EBUSY; | 591 | return -EBUSY; |
@@ -606,14 +601,12 @@ EXPORT_SYMBOL(d_invalidate); | |||
606 | /* This must be called with d_lock held */ | 601 | /* This must be called with d_lock held */ |
607 | static inline void __dget_dlock(struct dentry *dentry) | 602 | static inline void __dget_dlock(struct dentry *dentry) |
608 | { | 603 | { |
609 | dentry->d_count++; | 604 | dentry->d_lockref.count++; |
610 | } | 605 | } |
611 | 606 | ||
612 | static inline void __dget(struct dentry *dentry) | 607 | static inline void __dget(struct dentry *dentry) |
613 | { | 608 | { |
614 | spin_lock(&dentry->d_lock); | 609 | lockref_get(&dentry->d_lockref); |
615 | __dget_dlock(dentry); | ||
616 | spin_unlock(&dentry->d_lock); | ||
617 | } | 610 | } |
618 | 611 | ||
619 | struct dentry *dget_parent(struct dentry *dentry) | 612 | struct dentry *dget_parent(struct dentry *dentry) |
@@ -634,8 +627,8 @@ repeat: | |||
634 | goto repeat; | 627 | goto repeat; |
635 | } | 628 | } |
636 | rcu_read_unlock(); | 629 | rcu_read_unlock(); |
637 | BUG_ON(!ret->d_count); | 630 | BUG_ON(!ret->d_lockref.count); |
638 | ret->d_count++; | 631 | ret->d_lockref.count++; |
639 | spin_unlock(&ret->d_lock); | 632 | spin_unlock(&ret->d_lock); |
640 | return ret; | 633 | return ret; |
641 | } | 634 | } |
@@ -718,7 +711,7 @@ restart: | |||
718 | spin_lock(&inode->i_lock); | 711 | spin_lock(&inode->i_lock); |
719 | hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) { | 712 | hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) { |
720 | spin_lock(&dentry->d_lock); | 713 | spin_lock(&dentry->d_lock); |
721 | if (!dentry->d_count) { | 714 | if (!dentry->d_lockref.count) { |
722 | __dget_dlock(dentry); | 715 | __dget_dlock(dentry); |
723 | __d_drop(dentry); | 716 | __d_drop(dentry); |
724 | spin_unlock(&dentry->d_lock); | 717 | spin_unlock(&dentry->d_lock); |
@@ -763,12 +756,8 @@ static void try_prune_one_dentry(struct dentry *dentry) | |||
763 | /* Prune ancestors. */ | 756 | /* Prune ancestors. */ |
764 | dentry = parent; | 757 | dentry = parent; |
765 | while (dentry) { | 758 | while (dentry) { |
766 | spin_lock(&dentry->d_lock); | 759 | if (lockref_put_or_lock(&dentry->d_lockref)) |
767 | if (dentry->d_count > 1) { | ||
768 | dentry->d_count--; | ||
769 | spin_unlock(&dentry->d_lock); | ||
770 | return; | 760 | return; |
771 | } | ||
772 | dentry = dentry_kill(dentry, 1); | 761 | dentry = dentry_kill(dentry, 1); |
773 | } | 762 | } |
774 | } | 763 | } |
@@ -793,7 +782,7 @@ static void shrink_dentry_list(struct list_head *list) | |||
793 | * the LRU because of laziness during lookup. Do not free | 782 | * the LRU because of laziness during lookup. Do not free |
794 | * it - just keep it off the LRU list. | 783 | * it - just keep it off the LRU list. |
795 | */ | 784 | */ |
796 | if (dentry->d_count) { | 785 | if (dentry->d_lockref.count) { |
797 | dentry_lru_del(dentry); | 786 | dentry_lru_del(dentry); |
798 | spin_unlock(&dentry->d_lock); | 787 | spin_unlock(&dentry->d_lock); |
799 | continue; | 788 | continue; |
@@ -913,7 +902,7 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry) | |||
913 | dentry_lru_del(dentry); | 902 | dentry_lru_del(dentry); |
914 | __d_shrink(dentry); | 903 | __d_shrink(dentry); |
915 | 904 | ||
916 | if (dentry->d_count != 0) { | 905 | if (dentry->d_lockref.count != 0) { |
917 | printk(KERN_ERR | 906 | printk(KERN_ERR |
918 | "BUG: Dentry %p{i=%lx,n=%s}" | 907 | "BUG: Dentry %p{i=%lx,n=%s}" |
919 | " still in use (%d)" | 908 | " still in use (%d)" |
@@ -922,7 +911,7 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry) | |||
922 | dentry->d_inode ? | 911 | dentry->d_inode ? |
923 | dentry->d_inode->i_ino : 0UL, | 912 | dentry->d_inode->i_ino : 0UL, |
924 | dentry->d_name.name, | 913 | dentry->d_name.name, |
925 | dentry->d_count, | 914 | dentry->d_lockref.count, |
926 | dentry->d_sb->s_type->name, | 915 | dentry->d_sb->s_type->name, |
927 | dentry->d_sb->s_id); | 916 | dentry->d_sb->s_id); |
928 | BUG(); | 917 | BUG(); |
@@ -933,7 +922,7 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry) | |||
933 | list_del(&dentry->d_u.d_child); | 922 | list_del(&dentry->d_u.d_child); |
934 | } else { | 923 | } else { |
935 | parent = dentry->d_parent; | 924 | parent = dentry->d_parent; |
936 | parent->d_count--; | 925 | parent->d_lockref.count--; |
937 | list_del(&dentry->d_u.d_child); | 926 | list_del(&dentry->d_u.d_child); |
938 | } | 927 | } |
939 | 928 | ||
@@ -981,7 +970,7 @@ void shrink_dcache_for_umount(struct super_block *sb) | |||
981 | 970 | ||
982 | dentry = sb->s_root; | 971 | dentry = sb->s_root; |
983 | sb->s_root = NULL; | 972 | sb->s_root = NULL; |
984 | dentry->d_count--; | 973 | dentry->d_lockref.count--; |
985 | shrink_dcache_for_umount_subtree(dentry); | 974 | shrink_dcache_for_umount_subtree(dentry); |
986 | 975 | ||
987 | while (!hlist_bl_empty(&sb->s_anon)) { | 976 | while (!hlist_bl_empty(&sb->s_anon)) { |
@@ -1147,7 +1136,7 @@ resume: | |||
1147 | * loop in shrink_dcache_parent() might not make any progress | 1136 | * loop in shrink_dcache_parent() might not make any progress |
1148 | * and loop forever. | 1137 | * and loop forever. |
1149 | */ | 1138 | */ |
1150 | if (dentry->d_count) { | 1139 | if (dentry->d_lockref.count) { |
1151 | dentry_lru_del(dentry); | 1140 | dentry_lru_del(dentry); |
1152 | } else if (!(dentry->d_flags & DCACHE_SHRINK_LIST)) { | 1141 | } else if (!(dentry->d_flags & DCACHE_SHRINK_LIST)) { |
1153 | dentry_lru_move_list(dentry, dispose); | 1142 | dentry_lru_move_list(dentry, dispose); |
@@ -1269,7 +1258,7 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name) | |||
1269 | smp_wmb(); | 1258 | smp_wmb(); |
1270 | dentry->d_name.name = dname; | 1259 | dentry->d_name.name = dname; |
1271 | 1260 | ||
1272 | dentry->d_count = 1; | 1261 | dentry->d_lockref.count = 1; |
1273 | dentry->d_flags = 0; | 1262 | dentry->d_flags = 0; |
1274 | spin_lock_init(&dentry->d_lock); | 1263 | spin_lock_init(&dentry->d_lock); |
1275 | seqcount_init(&dentry->d_seq); | 1264 | seqcount_init(&dentry->d_seq); |
@@ -1970,7 +1959,7 @@ struct dentry *__d_lookup(const struct dentry *parent, const struct qstr *name) | |||
1970 | goto next; | 1959 | goto next; |
1971 | } | 1960 | } |
1972 | 1961 | ||
1973 | dentry->d_count++; | 1962 | dentry->d_lockref.count++; |
1974 | found = dentry; | 1963 | found = dentry; |
1975 | spin_unlock(&dentry->d_lock); | 1964 | spin_unlock(&dentry->d_lock); |
1976 | break; | 1965 | break; |
@@ -2069,7 +2058,7 @@ again: | |||
2069 | spin_lock(&dentry->d_lock); | 2058 | spin_lock(&dentry->d_lock); |
2070 | inode = dentry->d_inode; | 2059 | inode = dentry->d_inode; |
2071 | isdir = S_ISDIR(inode->i_mode); | 2060 | isdir = S_ISDIR(inode->i_mode); |
2072 | if (dentry->d_count == 1) { | 2061 | if (dentry->d_lockref.count == 1) { |
2073 | if (!spin_trylock(&inode->i_lock)) { | 2062 | if (!spin_trylock(&inode->i_lock)) { |
2074 | spin_unlock(&dentry->d_lock); | 2063 | spin_unlock(&dentry->d_lock); |
2075 | cpu_relax(); | 2064 | cpu_relax(); |
@@ -2724,6 +2713,17 @@ char *dynamic_dname(struct dentry *dentry, char *buffer, int buflen, | |||
2724 | return memcpy(buffer, temp, sz); | 2713 | return memcpy(buffer, temp, sz); |
2725 | } | 2714 | } |
2726 | 2715 | ||
2716 | char *simple_dname(struct dentry *dentry, char *buffer, int buflen) | ||
2717 | { | ||
2718 | char *end = buffer + buflen; | ||
2719 | /* these dentries are never renamed, so d_lock is not needed */ | ||
2720 | if (prepend(&end, &buflen, " (deleted)", 11) || | ||
2721 | prepend_name(&end, &buflen, &dentry->d_name) || | ||
2722 | prepend(&end, &buflen, "/", 1)) | ||
2723 | end = ERR_PTR(-ENAMETOOLONG); | ||
2724 | return end; | ||
2725 | } | ||
2726 | |||
2727 | /* | 2727 | /* |
2728 | * Write full pathname from the root of the filesystem into the buffer. | 2728 | * Write full pathname from the root of the filesystem into the buffer. |
2729 | */ | 2729 | */ |
@@ -2937,7 +2937,7 @@ resume: | |||
2937 | } | 2937 | } |
2938 | if (!(dentry->d_flags & DCACHE_GENOCIDE)) { | 2938 | if (!(dentry->d_flags & DCACHE_GENOCIDE)) { |
2939 | dentry->d_flags |= DCACHE_GENOCIDE; | 2939 | dentry->d_flags |= DCACHE_GENOCIDE; |
2940 | dentry->d_count--; | 2940 | dentry->d_lockref.count--; |
2941 | } | 2941 | } |
2942 | spin_unlock(&dentry->d_lock); | 2942 | spin_unlock(&dentry->d_lock); |
2943 | } | 2943 | } |
@@ -2945,7 +2945,7 @@ resume: | |||
2945 | struct dentry *child = this_parent; | 2945 | struct dentry *child = this_parent; |
2946 | if (!(this_parent->d_flags & DCACHE_GENOCIDE)) { | 2946 | if (!(this_parent->d_flags & DCACHE_GENOCIDE)) { |
2947 | this_parent->d_flags |= DCACHE_GENOCIDE; | 2947 | this_parent->d_flags |= DCACHE_GENOCIDE; |
2948 | this_parent->d_count--; | 2948 | this_parent->d_lockref.count--; |
2949 | } | 2949 | } |
2950 | this_parent = try_to_ascend(this_parent, locked, seq); | 2950 | this_parent = try_to_ascend(this_parent, locked, seq); |
2951 | if (!this_parent) | 2951 | if (!this_parent) |