aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/xfs/xfs_iget.c18
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
196out_unlock: 197out_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();
200out_unlock:
201 if (lock_flags)
202 xfs_iunlock(ip, lock_flags);
199out_destroy: 203out_destroy:
200 xfs_idestroy(ip); 204 xfs_idestroy(ip);
201 return error; 205 return error;