diff options
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index fe19ac13f75f..bcbdb33fcc20 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -104,7 +104,7 @@ static unsigned int d_hash_shift __read_mostly; | |||
104 | 104 | ||
105 | static struct hlist_bl_head *dentry_hashtable __read_mostly; | 105 | static struct hlist_bl_head *dentry_hashtable __read_mostly; |
106 | 106 | ||
107 | static inline struct hlist_bl_head *d_hash(struct dentry *parent, | 107 | static inline struct hlist_bl_head *d_hash(const struct dentry *parent, |
108 | unsigned long hash) | 108 | unsigned long hash) |
109 | { | 109 | { |
110 | hash += ((unsigned long) parent ^ GOLDEN_RATIO_PRIME) / L1_CACHE_BYTES; | 110 | hash += ((unsigned long) parent ^ GOLDEN_RATIO_PRIME) / L1_CACHE_BYTES; |
@@ -137,6 +137,26 @@ int proc_nr_dentry(ctl_table *table, int write, void __user *buffer, | |||
137 | } | 137 | } |
138 | #endif | 138 | #endif |
139 | 139 | ||
140 | /* | ||
141 | * Compare 2 name strings, return 0 if they match, otherwise non-zero. | ||
142 | * The strings are both count bytes long, and count is non-zero. | ||
143 | */ | ||
144 | static inline int dentry_cmp(const unsigned char *cs, size_t scount, | ||
145 | const unsigned char *ct, size_t tcount) | ||
146 | { | ||
147 | if (scount != tcount) | ||
148 | return 1; | ||
149 | |||
150 | do { | ||
151 | if (*cs != *ct) | ||
152 | return 1; | ||
153 | cs++; | ||
154 | ct++; | ||
155 | tcount--; | ||
156 | } while (tcount); | ||
157 | return 0; | ||
158 | } | ||
159 | |||
140 | static void __d_free(struct rcu_head *head) | 160 | static void __d_free(struct rcu_head *head) |
141 | { | 161 | { |
142 | struct dentry *dentry = container_of(head, struct dentry, d_u.d_rcu); | 162 | struct dentry *dentry = container_of(head, struct dentry, d_u.d_rcu); |
@@ -1717,8 +1737,9 @@ EXPORT_SYMBOL(d_add_ci); | |||
1717 | * child is looked up. Thus, an interlocking stepping of sequence lock checks | 1737 | * child is looked up. Thus, an interlocking stepping of sequence lock checks |
1718 | * is formed, giving integrity down the path walk. | 1738 | * is formed, giving integrity down the path walk. |
1719 | */ | 1739 | */ |
1720 | struct dentry *__d_lookup_rcu(struct dentry *parent, struct qstr *name, | 1740 | struct dentry *__d_lookup_rcu(const struct dentry *parent, |
1721 | unsigned *seq, struct inode **inode) | 1741 | const struct qstr *name, |
1742 | unsigned *seqp, struct inode **inode) | ||
1722 | { | 1743 | { |
1723 | unsigned int len = name->len; | 1744 | unsigned int len = name->len; |
1724 | unsigned int hash = name->hash; | 1745 | unsigned int hash = name->hash; |
@@ -1748,6 +1769,7 @@ struct dentry *__d_lookup_rcu(struct dentry *parent, struct qstr *name, | |||
1748 | * See Documentation/filesystems/path-lookup.txt for more details. | 1769 | * See Documentation/filesystems/path-lookup.txt for more details. |
1749 | */ | 1770 | */ |
1750 | hlist_bl_for_each_entry_rcu(dentry, node, b, d_hash) { | 1771 | hlist_bl_for_each_entry_rcu(dentry, node, b, d_hash) { |
1772 | unsigned seq; | ||
1751 | struct inode *i; | 1773 | struct inode *i; |
1752 | const char *tname; | 1774 | const char *tname; |
1753 | int tlen; | 1775 | int tlen; |
@@ -1756,7 +1778,7 @@ struct dentry *__d_lookup_rcu(struct dentry *parent, struct qstr *name, | |||
1756 | continue; | 1778 | continue; |
1757 | 1779 | ||
1758 | seqretry: | 1780 | seqretry: |
1759 | *seq = read_seqcount_begin(&dentry->d_seq); | 1781 | seq = read_seqcount_begin(&dentry->d_seq); |
1760 | if (dentry->d_parent != parent) | 1782 | if (dentry->d_parent != parent) |
1761 | continue; | 1783 | continue; |
1762 | if (d_unhashed(dentry)) | 1784 | if (d_unhashed(dentry)) |
@@ -1771,7 +1793,7 @@ seqretry: | |||
1771 | * edge of memory when walking. If we could load this | 1793 | * edge of memory when walking. If we could load this |
1772 | * atomically some other way, we could drop this check. | 1794 | * atomically some other way, we could drop this check. |
1773 | */ | 1795 | */ |
1774 | if (read_seqcount_retry(&dentry->d_seq, *seq)) | 1796 | if (read_seqcount_retry(&dentry->d_seq, seq)) |
1775 | goto seqretry; | 1797 | goto seqretry; |
1776 | if (unlikely(parent->d_flags & DCACHE_OP_COMPARE)) { | 1798 | if (unlikely(parent->d_flags & DCACHE_OP_COMPARE)) { |
1777 | if (parent->d_op->d_compare(parent, *inode, | 1799 | if (parent->d_op->d_compare(parent, *inode, |
@@ -1788,6 +1810,7 @@ seqretry: | |||
1788 | * order to do anything useful with the returned dentry | 1810 | * order to do anything useful with the returned dentry |
1789 | * anyway. | 1811 | * anyway. |
1790 | */ | 1812 | */ |
1813 | *seqp = seq; | ||
1791 | *inode = i; | 1814 | *inode = i; |
1792 | return dentry; | 1815 | return dentry; |
1793 | } | 1816 | } |