aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2008-04-22 03:34:12 -0400
committerLachlan McIlroy <lachlan@redback.melbourne.sgi.com>2008-04-29 01:54:24 -0400
commit1ac74e01df959e3e91baded7c83399372af945a2 (patch)
tree9d72cbcae16eaad8c0798a03cb9aa0c74249d795 /fs/xfs
parentcfa853e47df4fbee441ac0ac3fb592f076233145 (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/xfs')
-rw-r--r--fs/xfs/xfs_rename.c75
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}