diff options
Diffstat (limited to 'fs/btrfs/inode.c')
| -rw-r--r-- | fs/btrfs/inode.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 272b9b2bea86..59cba180fe83 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -3099,8 +3099,12 @@ static void inode_tree_add(struct inode *inode) | |||
| 3099 | { | 3099 | { |
| 3100 | struct btrfs_root *root = BTRFS_I(inode)->root; | 3100 | struct btrfs_root *root = BTRFS_I(inode)->root; |
| 3101 | struct btrfs_inode *entry; | 3101 | struct btrfs_inode *entry; |
| 3102 | struct rb_node **p = &root->inode_tree.rb_node; | 3102 | struct rb_node **p; |
| 3103 | struct rb_node *parent = NULL; | 3103 | struct rb_node *parent; |
| 3104 | |||
| 3105 | again: | ||
| 3106 | p = &root->inode_tree.rb_node; | ||
| 3107 | parent = NULL; | ||
| 3104 | 3108 | ||
| 3105 | spin_lock(&root->inode_lock); | 3109 | spin_lock(&root->inode_lock); |
| 3106 | while (*p) { | 3110 | while (*p) { |
| @@ -3108,13 +3112,16 @@ static void inode_tree_add(struct inode *inode) | |||
| 3108 | entry = rb_entry(parent, struct btrfs_inode, rb_node); | 3112 | entry = rb_entry(parent, struct btrfs_inode, rb_node); |
| 3109 | 3113 | ||
| 3110 | if (inode->i_ino < entry->vfs_inode.i_ino) | 3114 | if (inode->i_ino < entry->vfs_inode.i_ino) |
| 3111 | p = &(*p)->rb_left; | 3115 | p = &parent->rb_left; |
| 3112 | else if (inode->i_ino > entry->vfs_inode.i_ino) | 3116 | else if (inode->i_ino > entry->vfs_inode.i_ino) |
| 3113 | p = &(*p)->rb_right; | 3117 | p = &parent->rb_right; |
| 3114 | else { | 3118 | else { |
| 3115 | WARN_ON(!(entry->vfs_inode.i_state & | 3119 | WARN_ON(!(entry->vfs_inode.i_state & |
| 3116 | (I_WILL_FREE | I_FREEING | I_CLEAR))); | 3120 | (I_WILL_FREE | I_FREEING | I_CLEAR))); |
| 3117 | break; | 3121 | rb_erase(parent, &root->inode_tree); |
| 3122 | RB_CLEAR_NODE(parent); | ||
| 3123 | spin_unlock(&root->inode_lock); | ||
| 3124 | goto again; | ||
| 3118 | } | 3125 | } |
| 3119 | } | 3126 | } |
| 3120 | rb_link_node(&BTRFS_I(inode)->rb_node, parent, p); | 3127 | rb_link_node(&BTRFS_I(inode)->rb_node, parent, p); |
| @@ -3126,12 +3133,12 @@ static void inode_tree_del(struct inode *inode) | |||
| 3126 | { | 3133 | { |
| 3127 | struct btrfs_root *root = BTRFS_I(inode)->root; | 3134 | struct btrfs_root *root = BTRFS_I(inode)->root; |
| 3128 | 3135 | ||
| 3136 | spin_lock(&root->inode_lock); | ||
| 3129 | if (!RB_EMPTY_NODE(&BTRFS_I(inode)->rb_node)) { | 3137 | if (!RB_EMPTY_NODE(&BTRFS_I(inode)->rb_node)) { |
| 3130 | spin_lock(&root->inode_lock); | ||
| 3131 | rb_erase(&BTRFS_I(inode)->rb_node, &root->inode_tree); | 3138 | rb_erase(&BTRFS_I(inode)->rb_node, &root->inode_tree); |
| 3132 | spin_unlock(&root->inode_lock); | ||
| 3133 | RB_CLEAR_NODE(&BTRFS_I(inode)->rb_node); | 3139 | RB_CLEAR_NODE(&BTRFS_I(inode)->rb_node); |
| 3134 | } | 3140 | } |
| 3141 | spin_unlock(&root->inode_lock); | ||
| 3135 | } | 3142 | } |
| 3136 | 3143 | ||
| 3137 | static noinline void init_btrfs_i(struct inode *inode) | 3144 | static noinline void init_btrfs_i(struct inode *inode) |
