aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Chinner <david@fromorbit.com>2008-10-30 02:35:24 -0400
committerLachlan McIlroy <lachlan@redback.melbourne.sgi.com>2008-10-30 02:35:24 -0400
commit8290c35f87304a6b73d4fd17b03580b4f7425de8 (patch)
treecf7fb08de3fd7a6a1ccb079d2d5d53837aca16fe
parent2cb1599f9b2ecdd7a9e59feeee647eb258966839 (diff)
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>
-rw-r--r--fs/inode.c67
-rw-r--r--include/linux/fs.h1
2 files changed, 47 insertions, 21 deletions
diff --git a/fs/inode.c b/fs/inode.c
index e7ee99907d60..fbcf6c5e7605 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -550,6 +550,49 @@ repeat:
550 return node ? inode : NULL; 550 return node ? inode : NULL;
551} 551}
552 552
553static 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
563static 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
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 */
586void 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}
594EXPORT_SYMBOL_GPL(inode_add_to_lists);
595
553/** 596/**
554 * new_inode - obtain an inode 597 * new_inode - obtain an inode
555 * @sb: superblock 598 * @sb: superblock
@@ -577,9 +620,7 @@ struct inode *new_inode(struct super_block *sb)
577 inode = alloc_inode(sb); 620 inode = alloc_inode(sb);
578 if (inode) { 621 if (inode) {
579 spin_lock(&inode_lock); 622 spin_lock(&inode_lock);
580 inodes_stat.nr_inodes++; 623 __inode_add_to_lists(sb, NULL, inode);
581 list_add(&inode->i_list, &inode_in_use);
582 list_add(&inode->i_sb_list, &sb->s_inodes);
583 inode->i_ino = ++last_ino; 624 inode->i_ino = ++last_ino;
584 inode->i_state = 0; 625 inode->i_state = 0;
585 spin_unlock(&inode_lock); 626 spin_unlock(&inode_lock);
@@ -638,10 +679,7 @@ static struct inode * get_new_inode(struct super_block *sb, struct hlist_head *h
638 if (set(inode, data)) 679 if (set(inode, data))
639 goto set_failed; 680 goto set_failed;
640 681
641 inodes_stat.nr_inodes++; 682 __inode_add_to_lists(sb, head, inode);
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);
645 inode->i_state = I_LOCK|I_NEW; 683 inode->i_state = I_LOCK|I_NEW;
646 spin_unlock(&inode_lock); 684 spin_unlock(&inode_lock);
647 685
@@ -687,10 +725,7 @@ static struct inode * get_new_inode_fast(struct super_block *sb, struct hlist_he
687 old = find_inode_fast(sb, head, ino); 725 old = find_inode_fast(sb, head, ino);
688 if (!old) { 726 if (!old) {
689 inode->i_ino = ino; 727 inode->i_ino = ino;
690 inodes_stat.nr_inodes++; 728 __inode_add_to_lists(sb, head, inode);
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);
694 inode->i_state = I_LOCK|I_NEW; 729 inode->i_state = I_LOCK|I_NEW;
695 spin_unlock(&inode_lock); 730 spin_unlock(&inode_lock);
696 731
@@ -714,16 +749,6 @@ static struct inode * get_new_inode_fast(struct super_block *sb, struct hlist_he
714 return inode; 749 return inode;
715} 750}
716 751
717static 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}
726
727/** 752/**
728 * iunique - get a unique inode number 753 * iunique - get a unique inode number
729 * @sb: superblock 754 * @sb: superblock
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 04abead4b021..1deedf235d55 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1883,6 +1883,7 @@ extern loff_t vfs_llseek(struct file *file, loff_t offset, int origin);
1883 1883
1884extern struct inode * inode_init_always(struct super_block *, struct inode *); 1884extern struct inode * inode_init_always(struct super_block *, struct inode *);
1885extern void inode_init_once(struct inode *); 1885extern void inode_init_once(struct inode *);
1886extern void inode_add_to_lists(struct super_block *, struct inode *);
1886extern void iput(struct inode *); 1887extern void iput(struct inode *);
1887extern struct inode * igrab(struct inode *); 1888extern struct inode * igrab(struct inode *);
1888extern ino_t iunique(struct super_block *, ino_t); 1889extern ino_t iunique(struct super_block *, ino_t);