diff options
author | Christoph Hellwig <hch@infradead.org> | 2008-04-22 03:34:12 -0400 |
---|---|---|
committer | Lachlan McIlroy <lachlan@redback.melbourne.sgi.com> | 2008-04-29 01:54:24 -0400 |
commit | 1ac74e01df959e3e91baded7c83399372af945a2 (patch) | |
tree | 9d72cbcae16eaad8c0798a03cb9aa0c74249d795 /fs | |
parent | cfa853e47df4fbee441ac0ac3fb592f076233145 (diff) |
[XFS] kill usesless IHOLD calls in xfs_rename
Similar to to the previous patch for remove and rmdir only grab a
reference to inodes when we join them to transaction to balance the
decrement on transaction completion. Everything else it taken care of by
the VFS.
Note that the old case had leaks of inode count when src == target or src
or target == one of the parent inodes, but these cases are fortunately
already rejected by the VFS.
SGI-PV: 976035
SGI-Modid: xfs-linux-melb:xfs-kern:30904a
Signed-off-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/xfs_rename.c | 75 |
1 files changed, 10 insertions, 65 deletions
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c index 6a141427f68a..d8063e1ad298 100644 --- a/fs/xfs/xfs_rename.c +++ b/fs/xfs/xfs_rename.c | |||
@@ -137,9 +137,7 @@ xfs_rename( | |||
137 | int cancel_flags; | 137 | int cancel_flags; |
138 | int committed; | 138 | int committed; |
139 | xfs_inode_t *inodes[4]; | 139 | xfs_inode_t *inodes[4]; |
140 | int target_ip_dropped = 0; /* dropped target_ip link? */ | ||
141 | int spaceres; | 140 | int spaceres; |
142 | int target_link_zero = 0; | ||
143 | int num_inodes; | 141 | int num_inodes; |
144 | 142 | ||
145 | xfs_itrace_entry(src_dp); | 143 | xfs_itrace_entry(src_dp); |
@@ -174,10 +172,6 @@ xfs_rename( | |||
174 | xfs_sort_for_rename(src_dp, target_dp, src_ip, target_ip, | 172 | xfs_sort_for_rename(src_dp, target_dp, src_ip, target_ip, |
175 | inodes, &num_inodes); | 173 | inodes, &num_inodes); |
176 | 174 | ||
177 | IHOLD(src_ip); | ||
178 | if (target_ip) | ||
179 | IHOLD(target_ip); | ||
180 | |||
181 | XFS_BMAP_INIT(&free_list, &first_block); | 175 | XFS_BMAP_INIT(&free_list, &first_block); |
182 | tp = xfs_trans_alloc(mp, XFS_TRANS_RENAME); | 176 | tp = xfs_trans_alloc(mp, XFS_TRANS_RENAME); |
183 | cancel_flags = XFS_TRANS_RELEASE_LOG_RES; | 177 | cancel_flags = XFS_TRANS_RELEASE_LOG_RES; |
@@ -191,7 +185,7 @@ xfs_rename( | |||
191 | } | 185 | } |
192 | if (error) { | 186 | if (error) { |
193 | xfs_trans_cancel(tp, 0); | 187 | xfs_trans_cancel(tp, 0); |
194 | goto rele_return; | 188 | goto std_return; |
195 | } | 189 | } |
196 | 190 | ||
197 | /* | 191 | /* |
@@ -199,7 +193,7 @@ xfs_rename( | |||
199 | */ | 193 | */ |
200 | if ((error = XFS_QM_DQVOPRENAME(mp, inodes))) { | 194 | if ((error = XFS_QM_DQVOPRENAME(mp, inodes))) { |
201 | xfs_trans_cancel(tp, cancel_flags); | 195 | xfs_trans_cancel(tp, cancel_flags); |
202 | goto rele_return; | 196 | goto std_return; |
203 | } | 197 | } |
204 | 198 | ||
205 | /* | 199 | /* |
@@ -220,7 +214,7 @@ xfs_rename( | |||
220 | error = XFS_ERROR(EXDEV); | 214 | error = XFS_ERROR(EXDEV); |
221 | xfs_rename_unlock4(inodes, XFS_ILOCK_SHARED); | 215 | xfs_rename_unlock4(inodes, XFS_ILOCK_SHARED); |
222 | xfs_trans_cancel(tp, cancel_flags); | 216 | xfs_trans_cancel(tp, cancel_flags); |
223 | goto rele_return; | 217 | goto std_return; |
224 | } | 218 | } |
225 | 219 | ||
226 | /* | 220 | /* |
@@ -233,17 +227,17 @@ xfs_rename( | |||
233 | */ | 227 | */ |
234 | IHOLD(src_dp); | 228 | IHOLD(src_dp); |
235 | xfs_trans_ijoin(tp, src_dp, XFS_ILOCK_EXCL); | 229 | xfs_trans_ijoin(tp, src_dp, XFS_ILOCK_EXCL); |
230 | |||
236 | if (new_parent) { | 231 | if (new_parent) { |
237 | IHOLD(target_dp); | 232 | IHOLD(target_dp); |
238 | xfs_trans_ijoin(tp, target_dp, XFS_ILOCK_EXCL); | 233 | xfs_trans_ijoin(tp, target_dp, XFS_ILOCK_EXCL); |
239 | } | 234 | } |
240 | if ((src_ip != src_dp) && (src_ip != target_dp)) { | 235 | |
241 | xfs_trans_ijoin(tp, src_ip, XFS_ILOCK_EXCL); | 236 | IHOLD(src_ip); |
242 | } | 237 | xfs_trans_ijoin(tp, src_ip, XFS_ILOCK_EXCL); |
243 | if ((target_ip != NULL) && | 238 | |
244 | (target_ip != src_ip) && | 239 | if (target_ip) { |
245 | (target_ip != src_dp) && | 240 | IHOLD(target_ip); |
246 | (target_ip != target_dp)) { | ||
247 | xfs_trans_ijoin(tp, target_ip, XFS_ILOCK_EXCL); | 241 | xfs_trans_ijoin(tp, target_ip, XFS_ILOCK_EXCL); |
248 | } | 242 | } |
249 | 243 | ||
@@ -317,7 +311,6 @@ xfs_rename( | |||
317 | error = xfs_droplink(tp, target_ip); | 311 | error = xfs_droplink(tp, target_ip); |
318 | if (error) | 312 | if (error) |
319 | goto abort_return; | 313 | goto abort_return; |
320 | target_ip_dropped = 1; | ||
321 | 314 | ||
322 | if (src_is_directory) { | 315 | if (src_is_directory) { |
323 | /* | 316 | /* |
@@ -327,10 +320,6 @@ xfs_rename( | |||
327 | if (error) | 320 | if (error) |
328 | goto abort_return; | 321 | goto abort_return; |
329 | } | 322 | } |
330 | |||
331 | /* Do this test while we still hold the locks */ | ||
332 | target_link_zero = (target_ip)->i_d.di_nlink==0; | ||
333 | |||
334 | } /* target_ip != NULL */ | 323 | } /* target_ip != NULL */ |
335 | 324 | ||
336 | /* | 325 | /* |
@@ -397,15 +386,6 @@ xfs_rename( | |||
397 | } | 386 | } |
398 | 387 | ||
399 | /* | 388 | /* |
400 | * If there was a target inode, take an extra reference on | ||
401 | * it here so that it doesn't go to xfs_inactive() from | ||
402 | * within the commit. | ||
403 | */ | ||
404 | if (target_ip != NULL) { | ||
405 | IHOLD(target_ip); | ||
406 | } | ||
407 | |||
408 | /* | ||
409 | * If this is a synchronous mount, make sure that the | 389 | * If this is a synchronous mount, make sure that the |
410 | * rename transaction goes to disk before returning to | 390 | * rename transaction goes to disk before returning to |
411 | * the user. | 391 | * the user. |
@@ -414,30 +394,11 @@ xfs_rename( | |||
414 | xfs_trans_set_sync(tp); | 394 | xfs_trans_set_sync(tp); |
415 | } | 395 | } |
416 | 396 | ||
417 | /* | ||
418 | * Take refs. for vop_link_removed calls below. No need to worry | ||
419 | * about directory refs. because the caller holds them. | ||
420 | * | ||
421 | * Do holds before the xfs_bmap_finish since it might rele them down | ||
422 | * to zero. | ||
423 | */ | ||
424 | |||
425 | if (target_ip_dropped) | ||
426 | IHOLD(target_ip); | ||
427 | IHOLD(src_ip); | ||
428 | |||
429 | error = xfs_bmap_finish(&tp, &free_list, &committed); | 397 | error = xfs_bmap_finish(&tp, &free_list, &committed); |
430 | if (error) { | 398 | if (error) { |
431 | xfs_bmap_cancel(&free_list); | 399 | xfs_bmap_cancel(&free_list); |
432 | xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES | | 400 | xfs_trans_cancel(tp, (XFS_TRANS_RELEASE_LOG_RES | |
433 | XFS_TRANS_ABORT)); | 401 | XFS_TRANS_ABORT)); |
434 | if (target_ip != NULL) { | ||
435 | IRELE(target_ip); | ||
436 | } | ||
437 | if (target_ip_dropped) { | ||
438 | IRELE(target_ip); | ||
439 | } | ||
440 | IRELE(src_ip); | ||
441 | goto std_return; | 402 | goto std_return; |
442 | } | 403 | } |
443 | 404 | ||
@@ -446,15 +407,6 @@ xfs_rename( | |||
446 | * the vnode references. | 407 | * the vnode references. |
447 | */ | 408 | */ |
448 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | 409 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); |
449 | if (target_ip != NULL) | ||
450 | IRELE(target_ip); | ||
451 | /* | ||
452 | * Let interposed file systems know about removed links. | ||
453 | */ | ||
454 | if (target_ip_dropped) | ||
455 | IRELE(target_ip); | ||
456 | |||
457 | IRELE(src_ip); | ||
458 | 410 | ||
459 | /* Fall through to std_return with error = 0 or errno from | 411 | /* Fall through to std_return with error = 0 or errno from |
460 | * xfs_trans_commit */ | 412 | * xfs_trans_commit */ |
@@ -476,11 +428,4 @@ std_return: | |||
476 | xfs_bmap_cancel(&free_list); | 428 | xfs_bmap_cancel(&free_list); |
477 | xfs_trans_cancel(tp, cancel_flags); | 429 | xfs_trans_cancel(tp, cancel_flags); |
478 | goto std_return; | 430 | goto std_return; |
479 | |||
480 | rele_return: | ||
481 | IRELE(src_ip); | ||
482 | if (target_ip != NULL) { | ||
483 | IRELE(target_ip); | ||
484 | } | ||
485 | goto std_return; | ||
486 | } | 431 | } |