diff options
author | Dave Chinner <dchinner@redhat.com> | 2010-10-23 06:58:09 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2010-10-25 21:26:10 -0400 |
commit | 4c51acbc66f754e536e1c9e3331656b69bce86d0 (patch) | |
tree | f3b5bf0bfbadb04663d59a9dc42e7f57487d698c /fs/inode.c | |
parent | 9e38d86ff2d8a8db99570e982230861046df32b5 (diff) |
fs: Factor inode hash operations into functions
Before replacing the inode hash locking with a more scalable
mechanism, factor the removal of the inode from the hashes rather
than open coding it in several places.
Based on a patch originally from Nick Piggin.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/inode.c')
-rw-r--r-- | fs/inode.c | 100 |
1 files changed, 55 insertions, 45 deletions
diff --git a/fs/inode.c b/fs/inode.c index 3bdc76f1653a..5e5bafe70ceb 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -336,6 +336,58 @@ static void inode_lru_list_del(struct inode *inode) | |||
336 | } | 336 | } |
337 | } | 337 | } |
338 | 338 | ||
339 | static unsigned long hash(struct super_block *sb, unsigned long hashval) | ||
340 | { | ||
341 | unsigned long tmp; | ||
342 | |||
343 | tmp = (hashval * (unsigned long)sb) ^ (GOLDEN_RATIO_PRIME + hashval) / | ||
344 | L1_CACHE_BYTES; | ||
345 | tmp = tmp ^ ((tmp ^ GOLDEN_RATIO_PRIME) >> I_HASHBITS); | ||
346 | return tmp & I_HASHMASK; | ||
347 | } | ||
348 | |||
349 | /** | ||
350 | * __insert_inode_hash - hash an inode | ||
351 | * @inode: unhashed inode | ||
352 | * @hashval: unsigned long value used to locate this object in the | ||
353 | * inode_hashtable. | ||
354 | * | ||
355 | * Add an inode to the inode hash for this superblock. | ||
356 | */ | ||
357 | void __insert_inode_hash(struct inode *inode, unsigned long hashval) | ||
358 | { | ||
359 | struct hlist_head *head = inode_hashtable + hash(inode->i_sb, hashval); | ||
360 | spin_lock(&inode_lock); | ||
361 | hlist_add_head(&inode->i_hash, head); | ||
362 | spin_unlock(&inode_lock); | ||
363 | } | ||
364 | EXPORT_SYMBOL(__insert_inode_hash); | ||
365 | |||
366 | /** | ||
367 | * __remove_inode_hash - remove an inode from the hash | ||
368 | * @inode: inode to unhash | ||
369 | * | ||
370 | * Remove an inode from the superblock. | ||
371 | */ | ||
372 | static void __remove_inode_hash(struct inode *inode) | ||
373 | { | ||
374 | hlist_del_init(&inode->i_hash); | ||
375 | } | ||
376 | |||
377 | /** | ||
378 | * remove_inode_hash - remove an inode from the hash | ||
379 | * @inode: inode to unhash | ||
380 | * | ||
381 | * Remove an inode from the superblock. | ||
382 | */ | ||
383 | void remove_inode_hash(struct inode *inode) | ||
384 | { | ||
385 | spin_lock(&inode_lock); | ||
386 | hlist_del_init(&inode->i_hash); | ||
387 | spin_unlock(&inode_lock); | ||
388 | } | ||
389 | EXPORT_SYMBOL(remove_inode_hash); | ||
390 | |||
339 | void end_writeback(struct inode *inode) | 391 | void end_writeback(struct inode *inode) |
340 | { | 392 | { |
341 | might_sleep(); | 393 | might_sleep(); |
@@ -383,7 +435,7 @@ static void dispose_list(struct list_head *head) | |||
383 | evict(inode); | 435 | evict(inode); |
384 | 436 | ||
385 | spin_lock(&inode_lock); | 437 | spin_lock(&inode_lock); |
386 | hlist_del_init(&inode->i_hash); | 438 | __remove_inode_hash(inode); |
387 | list_del_init(&inode->i_sb_list); | 439 | list_del_init(&inode->i_sb_list); |
388 | spin_unlock(&inode_lock); | 440 | spin_unlock(&inode_lock); |
389 | 441 | ||
@@ -634,16 +686,6 @@ repeat: | |||
634 | return node ? inode : NULL; | 686 | return node ? inode : NULL; |
635 | } | 687 | } |
636 | 688 | ||
637 | static unsigned long hash(struct super_block *sb, unsigned long hashval) | ||
638 | { | ||
639 | unsigned long tmp; | ||
640 | |||
641 | tmp = (hashval * (unsigned long)sb) ^ (GOLDEN_RATIO_PRIME + hashval) / | ||
642 | L1_CACHE_BYTES; | ||
643 | tmp = tmp ^ ((tmp ^ GOLDEN_RATIO_PRIME) >> I_HASHBITS); | ||
644 | return tmp & I_HASHMASK; | ||
645 | } | ||
646 | |||
647 | static inline void | 689 | static inline void |
648 | __inode_add_to_lists(struct super_block *sb, struct hlist_head *head, | 690 | __inode_add_to_lists(struct super_block *sb, struct hlist_head *head, |
649 | struct inode *inode) | 691 | struct inode *inode) |
@@ -1194,36 +1236,6 @@ int insert_inode_locked4(struct inode *inode, unsigned long hashval, | |||
1194 | } | 1236 | } |
1195 | EXPORT_SYMBOL(insert_inode_locked4); | 1237 | EXPORT_SYMBOL(insert_inode_locked4); |
1196 | 1238 | ||
1197 | /** | ||
1198 | * __insert_inode_hash - hash an inode | ||
1199 | * @inode: unhashed inode | ||
1200 | * @hashval: unsigned long value used to locate this object in the | ||
1201 | * inode_hashtable. | ||
1202 | * | ||
1203 | * Add an inode to the inode hash for this superblock. | ||
1204 | */ | ||
1205 | void __insert_inode_hash(struct inode *inode, unsigned long hashval) | ||
1206 | { | ||
1207 | struct hlist_head *head = inode_hashtable + hash(inode->i_sb, hashval); | ||
1208 | spin_lock(&inode_lock); | ||
1209 | hlist_add_head(&inode->i_hash, head); | ||
1210 | spin_unlock(&inode_lock); | ||
1211 | } | ||
1212 | EXPORT_SYMBOL(__insert_inode_hash); | ||
1213 | |||
1214 | /** | ||
1215 | * remove_inode_hash - remove an inode from the hash | ||
1216 | * @inode: inode to unhash | ||
1217 | * | ||
1218 | * Remove an inode from the superblock. | ||
1219 | */ | ||
1220 | void remove_inode_hash(struct inode *inode) | ||
1221 | { | ||
1222 | spin_lock(&inode_lock); | ||
1223 | hlist_del_init(&inode->i_hash); | ||
1224 | spin_unlock(&inode_lock); | ||
1225 | } | ||
1226 | EXPORT_SYMBOL(remove_inode_hash); | ||
1227 | 1239 | ||
1228 | int generic_delete_inode(struct inode *inode) | 1240 | int generic_delete_inode(struct inode *inode) |
1229 | { | 1241 | { |
@@ -1279,7 +1291,7 @@ static void iput_final(struct inode *inode) | |||
1279 | spin_lock(&inode_lock); | 1291 | spin_lock(&inode_lock); |
1280 | WARN_ON(inode->i_state & I_NEW); | 1292 | WARN_ON(inode->i_state & I_NEW); |
1281 | inode->i_state &= ~I_WILL_FREE; | 1293 | inode->i_state &= ~I_WILL_FREE; |
1282 | hlist_del_init(&inode->i_hash); | 1294 | __remove_inode_hash(inode); |
1283 | } | 1295 | } |
1284 | WARN_ON(inode->i_state & I_NEW); | 1296 | WARN_ON(inode->i_state & I_NEW); |
1285 | inode->i_state |= I_FREEING; | 1297 | inode->i_state |= I_FREEING; |
@@ -1294,9 +1306,7 @@ static void iput_final(struct inode *inode) | |||
1294 | list_del_init(&inode->i_sb_list); | 1306 | list_del_init(&inode->i_sb_list); |
1295 | spin_unlock(&inode_lock); | 1307 | spin_unlock(&inode_lock); |
1296 | evict(inode); | 1308 | evict(inode); |
1297 | spin_lock(&inode_lock); | 1309 | remove_inode_hash(inode); |
1298 | hlist_del_init(&inode->i_hash); | ||
1299 | spin_unlock(&inode_lock); | ||
1300 | wake_up_inode(inode); | 1310 | wake_up_inode(inode); |
1301 | BUG_ON(inode->i_state != (I_FREEING | I_CLEAR)); | 1311 | BUG_ON(inode->i_state != (I_FREEING | I_CLEAR)); |
1302 | destroy_inode(inode); | 1312 | destroy_inode(inode); |