Commit 8290c35f87304a6b73d4fd17b03580b4f7425de8
Committed by
Lachlan McIlroy
1 parent
2cb1599f9b
Exists in
master
and in
7 other branches
Inode: Allow external list initialisation
To allow XFS to combine the XFS and linux inodes into a single structure, we need to drive inode lookup from the XFS inode cache, not the generic inode cache. This means that we need initialise a struct inode from a context outside alloc_inode() as it is no longer used by XFS. After inode allocation and initialisation, we need to add the inode to the superblock list, the in-use list, hash it and do some accounting. This all needs to be done with the inode_lock held and there are already several places in fs/inode.c that do this list manipulation. Factor out the common code, add a locking wrapper and export the function so ti can be called from XFS. Signed-off-by: Dave Chinner <david@fromorbit.com> Signed-off-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Showing 2 changed files with 47 additions and 21 deletions Side-by-side Diff
fs/inode.c
... | ... | @@ -550,7 +550,50 @@ |
550 | 550 | return node ? inode : NULL; |
551 | 551 | } |
552 | 552 | |
553 | +static unsigned long hash(struct super_block *sb, unsigned long hashval) | |
554 | +{ | |
555 | + unsigned long tmp; | |
556 | + | |
557 | + tmp = (hashval * (unsigned long)sb) ^ (GOLDEN_RATIO_PRIME + hashval) / | |
558 | + L1_CACHE_BYTES; | |
559 | + tmp = tmp ^ ((tmp ^ GOLDEN_RATIO_PRIME) >> I_HASHBITS); | |
560 | + return tmp & I_HASHMASK; | |
561 | +} | |
562 | + | |
563 | +static inline void | |
564 | +__inode_add_to_lists(struct super_block *sb, struct hlist_head *head, | |
565 | + struct inode *inode) | |
566 | +{ | |
567 | + inodes_stat.nr_inodes++; | |
568 | + list_add(&inode->i_list, &inode_in_use); | |
569 | + list_add(&inode->i_sb_list, &sb->s_inodes); | |
570 | + if (head) | |
571 | + hlist_add_head(&inode->i_hash, head); | |
572 | +} | |
573 | + | |
553 | 574 | /** |
575 | + * inode_add_to_lists - add a new inode to relevant lists | |
576 | + * @sb - superblock inode belongs to. | |
577 | + * @inode - inode to mark in use | |
578 | + * | |
579 | + * When an inode is allocated it needs to be accounted for, added to the in use | |
580 | + * list, the owning superblock and the inode hash. This needs to be done under | |
581 | + * the inode_lock, so export a function to do this rather than the inode lock | |
582 | + * itself. We calculate the hash list to add to here so it is all internal | |
583 | + * which requires the caller to have already set up the inode number in the | |
584 | + * inode to add. | |
585 | + */ | |
586 | +void inode_add_to_lists(struct super_block *sb, struct inode *inode) | |
587 | +{ | |
588 | + struct hlist_head *head = inode_hashtable + hash(sb, inode->i_ino); | |
589 | + | |
590 | + spin_lock(&inode_lock); | |
591 | + __inode_add_to_lists(sb, head, inode); | |
592 | + spin_unlock(&inode_lock); | |
593 | +} | |
594 | +EXPORT_SYMBOL_GPL(inode_add_to_lists); | |
595 | + | |
596 | +/** | |
554 | 597 | * new_inode - obtain an inode |
555 | 598 | * @sb: superblock |
556 | 599 | * |
... | ... | @@ -577,9 +620,7 @@ |
577 | 620 | inode = alloc_inode(sb); |
578 | 621 | if (inode) { |
579 | 622 | spin_lock(&inode_lock); |
580 | - inodes_stat.nr_inodes++; | |
581 | - list_add(&inode->i_list, &inode_in_use); | |
582 | - list_add(&inode->i_sb_list, &sb->s_inodes); | |
623 | + __inode_add_to_lists(sb, NULL, inode); | |
583 | 624 | inode->i_ino = ++last_ino; |
584 | 625 | inode->i_state = 0; |
585 | 626 | spin_unlock(&inode_lock); |
... | ... | @@ -638,10 +679,7 @@ |
638 | 679 | if (set(inode, data)) |
639 | 680 | goto set_failed; |
640 | 681 | |
641 | - inodes_stat.nr_inodes++; | |
642 | - list_add(&inode->i_list, &inode_in_use); | |
643 | - list_add(&inode->i_sb_list, &sb->s_inodes); | |
644 | - hlist_add_head(&inode->i_hash, head); | |
682 | + __inode_add_to_lists(sb, head, inode); | |
645 | 683 | inode->i_state = I_LOCK|I_NEW; |
646 | 684 | spin_unlock(&inode_lock); |
647 | 685 | |
... | ... | @@ -687,10 +725,7 @@ |
687 | 725 | old = find_inode_fast(sb, head, ino); |
688 | 726 | if (!old) { |
689 | 727 | inode->i_ino = ino; |
690 | - inodes_stat.nr_inodes++; | |
691 | - list_add(&inode->i_list, &inode_in_use); | |
692 | - list_add(&inode->i_sb_list, &sb->s_inodes); | |
693 | - hlist_add_head(&inode->i_hash, head); | |
728 | + __inode_add_to_lists(sb, head, inode); | |
694 | 729 | inode->i_state = I_LOCK|I_NEW; |
695 | 730 | spin_unlock(&inode_lock); |
696 | 731 | |
... | ... | @@ -712,16 +747,6 @@ |
712 | 747 | wait_on_inode(inode); |
713 | 748 | } |
714 | 749 | return inode; |
715 | -} | |
716 | - | |
717 | -static unsigned long hash(struct super_block *sb, unsigned long hashval) | |
718 | -{ | |
719 | - unsigned long tmp; | |
720 | - | |
721 | - tmp = (hashval * (unsigned long)sb) ^ (GOLDEN_RATIO_PRIME + hashval) / | |
722 | - L1_CACHE_BYTES; | |
723 | - tmp = tmp ^ ((tmp ^ GOLDEN_RATIO_PRIME) >> I_HASHBITS); | |
724 | - return tmp & I_HASHMASK; | |
725 | 750 | } |
726 | 751 | |
727 | 752 | /** |
include/linux/fs.h
... | ... | @@ -1883,6 +1883,7 @@ |
1883 | 1883 | |
1884 | 1884 | extern struct inode * inode_init_always(struct super_block *, struct inode *); |
1885 | 1885 | extern void inode_init_once(struct inode *); |
1886 | +extern void inode_add_to_lists(struct super_block *, struct inode *); | |
1886 | 1887 | extern void iput(struct inode *); |
1887 | 1888 | extern struct inode * igrab(struct inode *); |
1888 | 1889 | extern ino_t iunique(struct super_block *, ino_t); |