diff options
Diffstat (limited to 'fs/xfs/xfs_iget.c')
-rw-r--r-- | fs/xfs/xfs_iget.c | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index a1f209b0596f..377c0cd14999 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c | |||
@@ -159,18 +159,19 @@ xfs_iget_cache_miss( | |||
159 | goto out_destroy; | 159 | goto out_destroy; |
160 | } | 160 | } |
161 | 161 | ||
162 | if (lock_flags) | ||
163 | xfs_ilock(ip, lock_flags); | ||
164 | |||
162 | /* | 165 | /* |
163 | * Preload the radix tree so we can insert safely under the | 166 | * Preload the radix tree so we can insert safely under the |
164 | * write spinlock. | 167 | * write spinlock. Note that we cannot sleep inside the preload |
168 | * region. | ||
165 | */ | 169 | */ |
166 | if (radix_tree_preload(GFP_KERNEL)) { | 170 | if (radix_tree_preload(GFP_KERNEL)) { |
167 | error = EAGAIN; | 171 | error = EAGAIN; |
168 | goto out_destroy; | 172 | goto out_unlock; |
169 | } | 173 | } |
170 | 174 | ||
171 | if (lock_flags) | ||
172 | xfs_ilock(ip, lock_flags); | ||
173 | |||
174 | mask = ~(((XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)) - 1); | 175 | mask = ~(((XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)) - 1); |
175 | first_index = agino & mask; | 176 | first_index = agino & mask; |
176 | write_lock(&pag->pag_ici_lock); | 177 | write_lock(&pag->pag_ici_lock); |
@@ -181,7 +182,7 @@ xfs_iget_cache_miss( | |||
181 | WARN_ON(error != -EEXIST); | 182 | WARN_ON(error != -EEXIST); |
182 | XFS_STATS_INC(xs_ig_dup); | 183 | XFS_STATS_INC(xs_ig_dup); |
183 | error = EAGAIN; | 184 | error = EAGAIN; |
184 | goto out_unlock; | 185 | goto out_preload_end; |
185 | } | 186 | } |
186 | 187 | ||
187 | /* These values _must_ be set before releasing the radix tree lock! */ | 188 | /* These values _must_ be set before releasing the radix tree lock! */ |
@@ -193,9 +194,12 @@ xfs_iget_cache_miss( | |||
193 | *ipp = ip; | 194 | *ipp = ip; |
194 | return 0; | 195 | return 0; |
195 | 196 | ||
196 | out_unlock: | 197 | out_preload_end: |
197 | write_unlock(&pag->pag_ici_lock); | 198 | write_unlock(&pag->pag_ici_lock); |
198 | radix_tree_preload_end(); | 199 | radix_tree_preload_end(); |
200 | out_unlock: | ||
201 | if (lock_flags) | ||
202 | xfs_iunlock(ip, lock_flags); | ||
199 | out_destroy: | 203 | out_destroy: |
200 | xfs_idestroy(ip); | 204 | xfs_idestroy(ip); |
201 | return error; | 205 | return error; |