diff options
Diffstat (limited to 'fs/xfs/xfs_vnodeops.c')
-rw-r--r-- | fs/xfs/xfs_vnodeops.c | 285 |
1 files changed, 83 insertions, 202 deletions
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index b6a82d817a82..2a5c637344b4 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
@@ -146,11 +146,6 @@ xfs_readlink( | |||
146 | } | 146 | } |
147 | 147 | ||
148 | /* | 148 | /* |
149 | * Flags for xfs_free_eofblocks | ||
150 | */ | ||
151 | #define XFS_FREE_EOF_TRYLOCK (1<<0) | ||
152 | |||
153 | /* | ||
154 | * This is called by xfs_inactive to free any blocks beyond eof | 149 | * This is called by xfs_inactive to free any blocks beyond eof |
155 | * when the link count isn't zero and by xfs_dm_punch_hole() when | 150 | * when the link count isn't zero and by xfs_dm_punch_hole() when |
156 | * punching a hole to EOF. | 151 | * punching a hole to EOF. |
@@ -159,7 +154,7 @@ STATIC int | |||
159 | xfs_free_eofblocks( | 154 | xfs_free_eofblocks( |
160 | xfs_mount_t *mp, | 155 | xfs_mount_t *mp, |
161 | xfs_inode_t *ip, | 156 | xfs_inode_t *ip, |
162 | int flags) | 157 | bool need_iolock) |
163 | { | 158 | { |
164 | xfs_trans_t *tp; | 159 | xfs_trans_t *tp; |
165 | int error; | 160 | int error; |
@@ -174,7 +169,7 @@ xfs_free_eofblocks( | |||
174 | * of the file. If not, then there is nothing to do. | 169 | * of the file. If not, then there is nothing to do. |
175 | */ | 170 | */ |
176 | end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_ISIZE(ip)); | 171 | end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_ISIZE(ip)); |
177 | last_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_MAXIOFFSET(mp)); | 172 | last_fsb = XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes); |
178 | if (last_fsb <= end_fsb) | 173 | if (last_fsb <= end_fsb) |
179 | return 0; | 174 | return 0; |
180 | map_len = last_fsb - end_fsb; | 175 | map_len = last_fsb - end_fsb; |
@@ -201,13 +196,11 @@ xfs_free_eofblocks( | |||
201 | */ | 196 | */ |
202 | tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); | 197 | tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); |
203 | 198 | ||
204 | if (flags & XFS_FREE_EOF_TRYLOCK) { | 199 | if (need_iolock) { |
205 | if (!xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) { | 200 | if (!xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) { |
206 | xfs_trans_cancel(tp, 0); | 201 | xfs_trans_cancel(tp, 0); |
207 | return 0; | 202 | return 0; |
208 | } | 203 | } |
209 | } else { | ||
210 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | ||
211 | } | 204 | } |
212 | 205 | ||
213 | error = xfs_trans_reserve(tp, 0, | 206 | error = xfs_trans_reserve(tp, 0, |
@@ -217,7 +210,8 @@ xfs_free_eofblocks( | |||
217 | if (error) { | 210 | if (error) { |
218 | ASSERT(XFS_FORCED_SHUTDOWN(mp)); | 211 | ASSERT(XFS_FORCED_SHUTDOWN(mp)); |
219 | xfs_trans_cancel(tp, 0); | 212 | xfs_trans_cancel(tp, 0); |
220 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | 213 | if (need_iolock) |
214 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | ||
221 | return error; | 215 | return error; |
222 | } | 216 | } |
223 | 217 | ||
@@ -244,7 +238,10 @@ xfs_free_eofblocks( | |||
244 | error = xfs_trans_commit(tp, | 238 | error = xfs_trans_commit(tp, |
245 | XFS_TRANS_RELEASE_LOG_RES); | 239 | XFS_TRANS_RELEASE_LOG_RES); |
246 | } | 240 | } |
247 | xfs_iunlock(ip, XFS_IOLOCK_EXCL|XFS_ILOCK_EXCL); | 241 | |
242 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
243 | if (need_iolock) | ||
244 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | ||
248 | } | 245 | } |
249 | return error; | 246 | return error; |
250 | } | 247 | } |
@@ -282,23 +279,15 @@ xfs_inactive_symlink_rmt( | |||
282 | * free them all in one bunmapi call. | 279 | * free them all in one bunmapi call. |
283 | */ | 280 | */ |
284 | ASSERT(ip->i_d.di_nextents > 0 && ip->i_d.di_nextents <= 2); | 281 | ASSERT(ip->i_d.di_nextents > 0 && ip->i_d.di_nextents <= 2); |
285 | if ((error = xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0, | 282 | |
286 | XFS_TRANS_PERM_LOG_RES, XFS_ITRUNCATE_LOG_COUNT))) { | ||
287 | ASSERT(XFS_FORCED_SHUTDOWN(mp)); | ||
288 | xfs_trans_cancel(tp, 0); | ||
289 | *tpp = NULL; | ||
290 | return error; | ||
291 | } | ||
292 | /* | 283 | /* |
293 | * Lock the inode, fix the size, and join it to the transaction. | 284 | * Lock the inode, fix the size, and join it to the transaction. |
294 | * Hold it so in the normal path, we still have it locked for | 285 | * Hold it so in the normal path, we still have it locked for |
295 | * the second transaction. In the error paths we need it | 286 | * the second transaction. In the error paths we need it |
296 | * held so the cancel won't rele it, see below. | 287 | * held so the cancel won't rele it, see below. |
297 | */ | 288 | */ |
298 | xfs_ilock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL); | ||
299 | size = (int)ip->i_d.di_size; | 289 | size = (int)ip->i_d.di_size; |
300 | ip->i_d.di_size = 0; | 290 | ip->i_d.di_size = 0; |
301 | xfs_trans_ijoin(tp, ip, 0); | ||
302 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | 291 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); |
303 | /* | 292 | /* |
304 | * Find the block(s) so we can inval and unmap them. | 293 | * Find the block(s) so we can inval and unmap them. |
@@ -385,114 +374,14 @@ xfs_inactive_symlink_rmt( | |||
385 | ASSERT(XFS_FORCED_SHUTDOWN(mp)); | 374 | ASSERT(XFS_FORCED_SHUTDOWN(mp)); |
386 | goto error0; | 375 | goto error0; |
387 | } | 376 | } |
388 | /* | 377 | |
389 | * Return with the inode locked but not joined to the transaction. | 378 | xfs_trans_ijoin(tp, ip, 0); |
390 | */ | ||
391 | *tpp = tp; | 379 | *tpp = tp; |
392 | return 0; | 380 | return 0; |
393 | 381 | ||
394 | error1: | 382 | error1: |
395 | xfs_bmap_cancel(&free_list); | 383 | xfs_bmap_cancel(&free_list); |
396 | error0: | 384 | error0: |
397 | /* | ||
398 | * Have to come here with the inode locked and either | ||
399 | * (held and in the transaction) or (not in the transaction). | ||
400 | * If the inode isn't held then cancel would iput it, but | ||
401 | * that's wrong since this is inactive and the vnode ref | ||
402 | * count is 0 already. | ||
403 | * Cancel won't do anything to the inode if held, but it still | ||
404 | * needs to be locked until the cancel is done, if it was | ||
405 | * joined to the transaction. | ||
406 | */ | ||
407 | xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); | ||
408 | xfs_iunlock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL); | ||
409 | *tpp = NULL; | ||
410 | return error; | ||
411 | |||
412 | } | ||
413 | |||
414 | STATIC int | ||
415 | xfs_inactive_symlink_local( | ||
416 | xfs_inode_t *ip, | ||
417 | xfs_trans_t **tpp) | ||
418 | { | ||
419 | int error; | ||
420 | |||
421 | ASSERT(ip->i_d.di_size <= XFS_IFORK_DSIZE(ip)); | ||
422 | /* | ||
423 | * We're freeing a symlink which fit into | ||
424 | * the inode. Just free the memory used | ||
425 | * to hold the old symlink. | ||
426 | */ | ||
427 | error = xfs_trans_reserve(*tpp, 0, | ||
428 | XFS_ITRUNCATE_LOG_RES(ip->i_mount), | ||
429 | 0, XFS_TRANS_PERM_LOG_RES, | ||
430 | XFS_ITRUNCATE_LOG_COUNT); | ||
431 | |||
432 | if (error) { | ||
433 | xfs_trans_cancel(*tpp, 0); | ||
434 | *tpp = NULL; | ||
435 | return error; | ||
436 | } | ||
437 | xfs_ilock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); | ||
438 | |||
439 | /* | ||
440 | * Zero length symlinks _can_ exist. | ||
441 | */ | ||
442 | if (ip->i_df.if_bytes > 0) { | ||
443 | xfs_idata_realloc(ip, | ||
444 | -(ip->i_df.if_bytes), | ||
445 | XFS_DATA_FORK); | ||
446 | ASSERT(ip->i_df.if_bytes == 0); | ||
447 | } | ||
448 | return 0; | ||
449 | } | ||
450 | |||
451 | STATIC int | ||
452 | xfs_inactive_attrs( | ||
453 | xfs_inode_t *ip, | ||
454 | xfs_trans_t **tpp) | ||
455 | { | ||
456 | xfs_trans_t *tp; | ||
457 | int error; | ||
458 | xfs_mount_t *mp; | ||
459 | |||
460 | ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); | ||
461 | tp = *tpp; | ||
462 | mp = ip->i_mount; | ||
463 | ASSERT(ip->i_d.di_forkoff != 0); | ||
464 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); | ||
465 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | ||
466 | if (error) | ||
467 | goto error_unlock; | ||
468 | |||
469 | error = xfs_attr_inactive(ip); | ||
470 | if (error) | ||
471 | goto error_unlock; | ||
472 | |||
473 | tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); | ||
474 | error = xfs_trans_reserve(tp, 0, | ||
475 | XFS_IFREE_LOG_RES(mp), | ||
476 | 0, XFS_TRANS_PERM_LOG_RES, | ||
477 | XFS_INACTIVE_LOG_COUNT); | ||
478 | if (error) | ||
479 | goto error_cancel; | ||
480 | |||
481 | xfs_ilock(ip, XFS_ILOCK_EXCL); | ||
482 | xfs_trans_ijoin(tp, ip, 0); | ||
483 | xfs_idestroy_fork(ip, XFS_ATTR_FORK); | ||
484 | |||
485 | ASSERT(ip->i_d.di_anextents == 0); | ||
486 | |||
487 | *tpp = tp; | ||
488 | return 0; | ||
489 | |||
490 | error_cancel: | ||
491 | ASSERT(XFS_FORCED_SHUTDOWN(mp)); | ||
492 | xfs_trans_cancel(tp, 0); | ||
493 | error_unlock: | ||
494 | *tpp = NULL; | ||
495 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | ||
496 | return error; | 385 | return error; |
497 | } | 386 | } |
498 | 387 | ||
@@ -574,8 +463,7 @@ xfs_release( | |||
574 | if (xfs_iflags_test(ip, XFS_IDIRTY_RELEASE)) | 463 | if (xfs_iflags_test(ip, XFS_IDIRTY_RELEASE)) |
575 | return 0; | 464 | return 0; |
576 | 465 | ||
577 | error = xfs_free_eofblocks(mp, ip, | 466 | error = xfs_free_eofblocks(mp, ip, true); |
578 | XFS_FREE_EOF_TRYLOCK); | ||
579 | if (error) | 467 | if (error) |
580 | return error; | 468 | return error; |
581 | 469 | ||
@@ -604,7 +492,7 @@ xfs_inactive( | |||
604 | xfs_trans_t *tp; | 492 | xfs_trans_t *tp; |
605 | xfs_mount_t *mp; | 493 | xfs_mount_t *mp; |
606 | int error; | 494 | int error; |
607 | int truncate; | 495 | int truncate = 0; |
608 | 496 | ||
609 | /* | 497 | /* |
610 | * If the inode is already free, then there can be nothing | 498 | * If the inode is already free, then there can be nothing |
@@ -616,17 +504,6 @@ xfs_inactive( | |||
616 | return VN_INACTIVE_CACHE; | 504 | return VN_INACTIVE_CACHE; |
617 | } | 505 | } |
618 | 506 | ||
619 | /* | ||
620 | * Only do a truncate if it's a regular file with | ||
621 | * some actual space in it. It's OK to look at the | ||
622 | * inode's fields without the lock because we're the | ||
623 | * only one with a reference to the inode. | ||
624 | */ | ||
625 | truncate = ((ip->i_d.di_nlink == 0) && | ||
626 | ((ip->i_d.di_size != 0) || XFS_ISIZE(ip) != 0 || | ||
627 | (ip->i_d.di_nextents > 0) || (ip->i_delayed_blks > 0)) && | ||
628 | S_ISREG(ip->i_d.di_mode)); | ||
629 | |||
630 | mp = ip->i_mount; | 507 | mp = ip->i_mount; |
631 | 508 | ||
632 | error = 0; | 509 | error = 0; |
@@ -643,99 +520,100 @@ xfs_inactive( | |||
643 | (!(ip->i_d.di_flags & | 520 | (!(ip->i_d.di_flags & |
644 | (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) || | 521 | (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) || |
645 | ip->i_delayed_blks != 0))) { | 522 | ip->i_delayed_blks != 0))) { |
646 | error = xfs_free_eofblocks(mp, ip, 0); | 523 | error = xfs_free_eofblocks(mp, ip, false); |
647 | if (error) | 524 | if (error) |
648 | return VN_INACTIVE_CACHE; | 525 | return VN_INACTIVE_CACHE; |
649 | } | 526 | } |
650 | goto out; | 527 | goto out; |
651 | } | 528 | } |
652 | 529 | ||
653 | ASSERT(ip->i_d.di_nlink == 0); | 530 | if (S_ISREG(ip->i_d.di_mode) && |
531 | (ip->i_d.di_size != 0 || XFS_ISIZE(ip) != 0 || | ||
532 | ip->i_d.di_nextents > 0 || ip->i_delayed_blks > 0)) | ||
533 | truncate = 1; | ||
654 | 534 | ||
655 | error = xfs_qm_dqattach(ip, 0); | 535 | error = xfs_qm_dqattach(ip, 0); |
656 | if (error) | 536 | if (error) |
657 | return VN_INACTIVE_CACHE; | 537 | return VN_INACTIVE_CACHE; |
658 | 538 | ||
659 | tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); | 539 | tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); |
660 | if (truncate) { | 540 | error = xfs_trans_reserve(tp, 0, |
661 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | 541 | (truncate || S_ISLNK(ip->i_d.di_mode)) ? |
662 | 542 | XFS_ITRUNCATE_LOG_RES(mp) : | |
663 | error = xfs_trans_reserve(tp, 0, | 543 | XFS_IFREE_LOG_RES(mp), |
664 | XFS_ITRUNCATE_LOG_RES(mp), | 544 | 0, |
665 | 0, XFS_TRANS_PERM_LOG_RES, | 545 | XFS_TRANS_PERM_LOG_RES, |
666 | XFS_ITRUNCATE_LOG_COUNT); | 546 | XFS_ITRUNCATE_LOG_COUNT); |
667 | if (error) { | 547 | if (error) { |
668 | /* Don't call itruncate_cleanup */ | 548 | ASSERT(XFS_FORCED_SHUTDOWN(mp)); |
669 | ASSERT(XFS_FORCED_SHUTDOWN(mp)); | 549 | xfs_trans_cancel(tp, 0); |
670 | xfs_trans_cancel(tp, 0); | 550 | return VN_INACTIVE_CACHE; |
671 | xfs_iunlock(ip, XFS_IOLOCK_EXCL); | 551 | } |
672 | return VN_INACTIVE_CACHE; | ||
673 | } | ||
674 | 552 | ||
675 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 553 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
676 | xfs_trans_ijoin(tp, ip, 0); | 554 | xfs_trans_ijoin(tp, ip, 0); |
677 | 555 | ||
556 | if (S_ISLNK(ip->i_d.di_mode)) { | ||
557 | /* | ||
558 | * Zero length symlinks _can_ exist. | ||
559 | */ | ||
560 | if (ip->i_d.di_size > XFS_IFORK_DSIZE(ip)) { | ||
561 | error = xfs_inactive_symlink_rmt(ip, &tp); | ||
562 | if (error) | ||
563 | goto out_cancel; | ||
564 | } else if (ip->i_df.if_bytes > 0) { | ||
565 | xfs_idata_realloc(ip, -(ip->i_df.if_bytes), | ||
566 | XFS_DATA_FORK); | ||
567 | ASSERT(ip->i_df.if_bytes == 0); | ||
568 | } | ||
569 | } else if (truncate) { | ||
678 | ip->i_d.di_size = 0; | 570 | ip->i_d.di_size = 0; |
679 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | 571 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); |
680 | 572 | ||
681 | error = xfs_itruncate_extents(&tp, ip, XFS_DATA_FORK, 0); | 573 | error = xfs_itruncate_extents(&tp, ip, XFS_DATA_FORK, 0); |
682 | if (error) { | 574 | if (error) |
683 | xfs_trans_cancel(tp, | 575 | goto out_cancel; |
684 | XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); | ||
685 | xfs_iunlock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL); | ||
686 | return VN_INACTIVE_CACHE; | ||
687 | } | ||
688 | 576 | ||
689 | ASSERT(ip->i_d.di_nextents == 0); | 577 | ASSERT(ip->i_d.di_nextents == 0); |
690 | } else if (S_ISLNK(ip->i_d.di_mode)) { | 578 | } |
691 | 579 | ||
692 | /* | 580 | /* |
693 | * If we get an error while cleaning up a | 581 | * If there are attributes associated with the file then blow them away |
694 | * symlink we bail out. | 582 | * now. The code calls a routine that recursively deconstructs the |
695 | */ | 583 | * attribute fork. We need to just commit the current transaction |
696 | error = (ip->i_d.di_size > XFS_IFORK_DSIZE(ip)) ? | 584 | * because we can't use it for xfs_attr_inactive(). |
697 | xfs_inactive_symlink_rmt(ip, &tp) : | 585 | */ |
698 | xfs_inactive_symlink_local(ip, &tp); | 586 | if (ip->i_d.di_anextents > 0) { |
587 | ASSERT(ip->i_d.di_forkoff != 0); | ||
699 | 588 | ||
700 | if (error) { | 589 | error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES); |
701 | ASSERT(tp == NULL); | 590 | if (error) |
702 | return VN_INACTIVE_CACHE; | 591 | goto out_unlock; |
703 | } | ||
704 | 592 | ||
705 | xfs_trans_ijoin(tp, ip, 0); | 593 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
706 | } else { | 594 | |
595 | error = xfs_attr_inactive(ip); | ||
596 | if (error) | ||
597 | goto out; | ||
598 | |||
599 | tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE); | ||
707 | error = xfs_trans_reserve(tp, 0, | 600 | error = xfs_trans_reserve(tp, 0, |
708 | XFS_IFREE_LOG_RES(mp), | 601 | XFS_IFREE_LOG_RES(mp), |
709 | 0, XFS_TRANS_PERM_LOG_RES, | 602 | 0, XFS_TRANS_PERM_LOG_RES, |
710 | XFS_INACTIVE_LOG_COUNT); | 603 | XFS_INACTIVE_LOG_COUNT); |
711 | if (error) { | 604 | if (error) { |
712 | ASSERT(XFS_FORCED_SHUTDOWN(mp)); | ||
713 | xfs_trans_cancel(tp, 0); | 605 | xfs_trans_cancel(tp, 0); |
714 | return VN_INACTIVE_CACHE; | 606 | goto out; |
715 | } | 607 | } |
716 | 608 | ||
717 | xfs_ilock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); | 609 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
718 | xfs_trans_ijoin(tp, ip, 0); | 610 | xfs_trans_ijoin(tp, ip, 0); |
719 | } | 611 | } |
720 | 612 | ||
721 | /* | 613 | if (ip->i_afp) |
722 | * If there are attributes associated with the file | ||
723 | * then blow them away now. The code calls a routine | ||
724 | * that recursively deconstructs the attribute fork. | ||
725 | * We need to just commit the current transaction | ||
726 | * because we can't use it for xfs_attr_inactive(). | ||
727 | */ | ||
728 | if (ip->i_d.di_anextents > 0) { | ||
729 | error = xfs_inactive_attrs(ip, &tp); | ||
730 | /* | ||
731 | * If we got an error, the transaction is already | ||
732 | * cancelled, and the inode is unlocked. Just get out. | ||
733 | */ | ||
734 | if (error) | ||
735 | return VN_INACTIVE_CACHE; | ||
736 | } else if (ip->i_afp) { | ||
737 | xfs_idestroy_fork(ip, XFS_ATTR_FORK); | 614 | xfs_idestroy_fork(ip, XFS_ATTR_FORK); |
738 | } | 615 | |
616 | ASSERT(ip->i_d.di_anextents == 0); | ||
739 | 617 | ||
740 | /* | 618 | /* |
741 | * Free the inode. | 619 | * Free the inode. |
@@ -779,10 +657,13 @@ xfs_inactive( | |||
779 | * Release the dquots held by inode, if any. | 657 | * Release the dquots held by inode, if any. |
780 | */ | 658 | */ |
781 | xfs_qm_dqdetach(ip); | 659 | xfs_qm_dqdetach(ip); |
782 | xfs_iunlock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL); | 660 | out_unlock: |
783 | 661 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | |
784 | out: | 662 | out: |
785 | return VN_INACTIVE_CACHE; | 663 | return VN_INACTIVE_CACHE; |
664 | out_cancel: | ||
665 | xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); | ||
666 | goto out_unlock; | ||
786 | } | 667 | } |
787 | 668 | ||
788 | /* | 669 | /* |
@@ -2262,10 +2143,10 @@ xfs_change_file_space( | |||
2262 | 2143 | ||
2263 | llen = bf->l_len > 0 ? bf->l_len - 1 : bf->l_len; | 2144 | llen = bf->l_len > 0 ? bf->l_len - 1 : bf->l_len; |
2264 | 2145 | ||
2265 | if ( (bf->l_start < 0) | 2146 | if (bf->l_start < 0 || |
2266 | || (bf->l_start > XFS_MAXIOFFSET(mp)) | 2147 | bf->l_start > mp->m_super->s_maxbytes || |
2267 | || (bf->l_start + llen < 0) | 2148 | bf->l_start + llen < 0 || |
2268 | || (bf->l_start + llen > XFS_MAXIOFFSET(mp))) | 2149 | bf->l_start + llen > mp->m_super->s_maxbytes) |
2269 | return XFS_ERROR(EINVAL); | 2150 | return XFS_ERROR(EINVAL); |
2270 | 2151 | ||
2271 | bf->l_whence = 0; | 2152 | bf->l_whence = 0; |