lkml.org 
[lkml]   [2010]   [Jun]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 33/52] fs: icache atomic last_ino, iunique lock
    Make last_ino atomic in preperation for removing inode_lock.
    Make a new lock for iunique counter, for removing inode_lock.

    Signed-off-by: Nick Piggin <npiggin@suse.de>
    ---
    fs/inode.c | 28 ++++++++++++++++++++++------
    1 file changed, 22 insertions(+), 6 deletions(-)

    Index: linux-2.6/fs/inode.c
    ===================================================================
    --- linux-2.6.orig/fs/inode.c
    +++ linux-2.6/fs/inode.c
    @@ -742,7 +742,7 @@ struct inode *new_inode(struct super_blo
    * error if st_ino won't fit in target struct field. Use 32bit counter
    * here to attempt to avoid that.
    */
    - static unsigned int last_ino;
    + static atomic_t last_ino = ATOMIC_INIT(0);
    struct inode *inode;

    spin_lock_prefetch(&inode_lock);
    @@ -752,7 +752,7 @@ struct inode *new_inode(struct super_blo
    spin_lock(&inode_lock);
    spin_lock(&sb_inode_list_lock);
    spin_lock(&inode->i_lock);
    - inode->i_ino = ++last_ino;
    + inode->i_ino = atomic_inc_return(&last_ino);
    inode->i_state = 0;
    __inode_add_to_lists(sb, NULL, inode);
    spin_unlock(&inode->i_lock);
    @@ -903,6 +903,22 @@ static struct inode *get_new_inode_fast(
    return inode;
    }

    +static int test_inode_iunique(struct super_block * sb, struct hlist_head *head, unsigned long ino)
    +{
    + struct hlist_node *node;
    + struct inode * inode = NULL;
    +
    + spin_lock(&inode_hash_lock);
    + hlist_for_each_entry(inode, node, head, i_hash) {
    + if (inode->i_ino == ino && inode->i_sb == sb) {
    + spin_unlock(&inode_hash_lock);
    + return 0;
    + }
    + }
    + spin_unlock(&inode_hash_lock);
    + return 1;
    +}
    +
    /**
    * iunique - get a unique inode number
    * @sb: superblock
    @@ -924,20 +940,20 @@ ino_t iunique(struct super_block *sb, in
    * error if st_ino won't fit in target struct field. Use 32bit counter
    * here to attempt to avoid that.
    */
    + static DEFINE_SPINLOCK(unique_lock);
    static unsigned int counter;
    - struct inode *inode;
    struct hlist_head *head;
    ino_t res;

    spin_lock(&inode_lock);
    + spin_lock(&unique_lock);
    do {
    if (counter <= max_reserved)
    counter = max_reserved + 1;
    res = counter++;
    head = inode_hashtable + hash(sb, res);
    - inode = find_inode_fast(sb, head, res);
    - spin_unlock(&inode->i_lock);
    - } while (inode != NULL);
    + } while (!test_inode_iunique(sb, head, res));
    + spin_unlock(&unique_lock);
    spin_unlock(&inode_lock);

    return res;



    \
     
     \ /
      Last update: 2010-06-24 05:23    [W:4.190 / U:0.108 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site