diff options
| author | Ingo Molnar <mingo@elte.hu> | 2008-08-14 06:19:59 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2008-08-14 06:19:59 -0400 |
| commit | 8d7ccaa545490cdffdfaff0842436a8dd85cf47b (patch) | |
| tree | 8129b5907161bc6ae26deb3645ce1e280c5e1f51 /fs/xfs/xfs_inode.c | |
| parent | b2139aa0eec330c711c5a279db361e5ef1178e78 (diff) | |
| parent | 30a2f3c60a84092c8084dfe788b710f8d0768cd4 (diff) | |
Merge commit 'v2.6.27-rc3' into x86/prototypes
Conflicts:
include/asm-x86/dma-mapping.h
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'fs/xfs/xfs_inode.c')
| -rw-r--r-- | fs/xfs/xfs_inode.c | 165 |
1 files changed, 62 insertions, 103 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index e569bf5d6cf0..bedc66163176 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
| @@ -1763,67 +1763,6 @@ xfs_itruncate_finish( | |||
| 1763 | return 0; | 1763 | return 0; |
| 1764 | } | 1764 | } |
| 1765 | 1765 | ||
| 1766 | |||
| 1767 | /* | ||
| 1768 | * xfs_igrow_start | ||
| 1769 | * | ||
| 1770 | * Do the first part of growing a file: zero any data in the last | ||
| 1771 | * block that is beyond the old EOF. We need to do this before | ||
| 1772 | * the inode is joined to the transaction to modify the i_size. | ||
| 1773 | * That way we can drop the inode lock and call into the buffer | ||
| 1774 | * cache to get the buffer mapping the EOF. | ||
| 1775 | */ | ||
| 1776 | int | ||
| 1777 | xfs_igrow_start( | ||
| 1778 | xfs_inode_t *ip, | ||
| 1779 | xfs_fsize_t new_size, | ||
| 1780 | cred_t *credp) | ||
| 1781 | { | ||
| 1782 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL)); | ||
| 1783 | ASSERT(new_size > ip->i_size); | ||
| 1784 | |||
| 1785 | /* | ||
| 1786 | * Zero any pages that may have been created by | ||
| 1787 | * xfs_write_file() beyond the end of the file | ||
| 1788 | * and any blocks between the old and new file sizes. | ||
| 1789 | */ | ||
| 1790 | return xfs_zero_eof(ip, new_size, ip->i_size); | ||
| 1791 | } | ||
| 1792 | |||
| 1793 | /* | ||
| 1794 | * xfs_igrow_finish | ||
| 1795 | * | ||
| 1796 | * This routine is called to extend the size of a file. | ||
| 1797 | * The inode must have both the iolock and the ilock locked | ||
| 1798 | * for update and it must be a part of the current transaction. | ||
| 1799 | * The xfs_igrow_start() function must have been called previously. | ||
| 1800 | * If the change_flag is not zero, the inode change timestamp will | ||
| 1801 | * be updated. | ||
| 1802 | */ | ||
| 1803 | void | ||
| 1804 | xfs_igrow_finish( | ||
| 1805 | xfs_trans_t *tp, | ||
| 1806 | xfs_inode_t *ip, | ||
| 1807 | xfs_fsize_t new_size, | ||
| 1808 | int change_flag) | ||
| 1809 | { | ||
| 1810 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL)); | ||
| 1811 | ASSERT(ip->i_transp == tp); | ||
| 1812 | ASSERT(new_size > ip->i_size); | ||
| 1813 | |||
| 1814 | /* | ||
| 1815 | * Update the file size. Update the inode change timestamp | ||
| 1816 | * if change_flag set. | ||
| 1817 | */ | ||
| 1818 | ip->i_d.di_size = new_size; | ||
| 1819 | ip->i_size = new_size; | ||
| 1820 | if (change_flag) | ||
| 1821 | xfs_ichgtime(ip, XFS_ICHGTIME_CHG); | ||
| 1822 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | ||
| 1823 | |||
| 1824 | } | ||
| 1825 | |||
| 1826 | |||
| 1827 | /* | 1766 | /* |
| 1828 | * This is called when the inode's link count goes to 0. | 1767 | * This is called when the inode's link count goes to 0. |
| 1829 | * We place the on-disk inode on a list in the AGI. It | 1768 | * We place the on-disk inode on a list in the AGI. It |
| @@ -2258,7 +2197,7 @@ xfs_ifree_cluster( | |||
| 2258 | xfs_trans_binval(tp, bp); | 2197 | xfs_trans_binval(tp, bp); |
| 2259 | } | 2198 | } |
| 2260 | 2199 | ||
| 2261 | kmem_free(ip_found, ninodes * sizeof(xfs_inode_t *)); | 2200 | kmem_free(ip_found); |
| 2262 | xfs_put_perag(mp, pag); | 2201 | xfs_put_perag(mp, pag); |
| 2263 | } | 2202 | } |
| 2264 | 2203 | ||
| @@ -2470,7 +2409,7 @@ xfs_iroot_realloc( | |||
| 2470 | (int)new_size); | 2409 | (int)new_size); |
| 2471 | memcpy(np, op, new_max * (uint)sizeof(xfs_dfsbno_t)); | 2410 | memcpy(np, op, new_max * (uint)sizeof(xfs_dfsbno_t)); |
| 2472 | } | 2411 | } |
| 2473 | kmem_free(ifp->if_broot, ifp->if_broot_bytes); | 2412 | kmem_free(ifp->if_broot); |
| 2474 | ifp->if_broot = new_broot; | 2413 | ifp->if_broot = new_broot; |
| 2475 | ifp->if_broot_bytes = (int)new_size; | 2414 | ifp->if_broot_bytes = (int)new_size; |
| 2476 | ASSERT(ifp->if_broot_bytes <= | 2415 | ASSERT(ifp->if_broot_bytes <= |
| @@ -2514,7 +2453,7 @@ xfs_idata_realloc( | |||
| 2514 | 2453 | ||
| 2515 | if (new_size == 0) { | 2454 | if (new_size == 0) { |
| 2516 | if (ifp->if_u1.if_data != ifp->if_u2.if_inline_data) { | 2455 | if (ifp->if_u1.if_data != ifp->if_u2.if_inline_data) { |
| 2517 | kmem_free(ifp->if_u1.if_data, ifp->if_real_bytes); | 2456 | kmem_free(ifp->if_u1.if_data); |
| 2518 | } | 2457 | } |
| 2519 | ifp->if_u1.if_data = NULL; | 2458 | ifp->if_u1.if_data = NULL; |
| 2520 | real_size = 0; | 2459 | real_size = 0; |
| @@ -2529,7 +2468,7 @@ xfs_idata_realloc( | |||
| 2529 | ASSERT(ifp->if_real_bytes != 0); | 2468 | ASSERT(ifp->if_real_bytes != 0); |
| 2530 | memcpy(ifp->if_u2.if_inline_data, ifp->if_u1.if_data, | 2469 | memcpy(ifp->if_u2.if_inline_data, ifp->if_u1.if_data, |
| 2531 | new_size); | 2470 | new_size); |
| 2532 | kmem_free(ifp->if_u1.if_data, ifp->if_real_bytes); | 2471 | kmem_free(ifp->if_u1.if_data); |
| 2533 | ifp->if_u1.if_data = ifp->if_u2.if_inline_data; | 2472 | ifp->if_u1.if_data = ifp->if_u2.if_inline_data; |
| 2534 | } | 2473 | } |
| 2535 | real_size = 0; | 2474 | real_size = 0; |
| @@ -2636,7 +2575,7 @@ xfs_idestroy_fork( | |||
| 2636 | 2575 | ||
| 2637 | ifp = XFS_IFORK_PTR(ip, whichfork); | 2576 | ifp = XFS_IFORK_PTR(ip, whichfork); |
| 2638 | if (ifp->if_broot != NULL) { | 2577 | if (ifp->if_broot != NULL) { |
| 2639 | kmem_free(ifp->if_broot, ifp->if_broot_bytes); | 2578 | kmem_free(ifp->if_broot); |
| 2640 | ifp->if_broot = NULL; | 2579 | ifp->if_broot = NULL; |
| 2641 | } | 2580 | } |
| 2642 | 2581 | ||
| @@ -2650,7 +2589,7 @@ xfs_idestroy_fork( | |||
| 2650 | if ((ifp->if_u1.if_data != ifp->if_u2.if_inline_data) && | 2589 | if ((ifp->if_u1.if_data != ifp->if_u2.if_inline_data) && |
| 2651 | (ifp->if_u1.if_data != NULL)) { | 2590 | (ifp->if_u1.if_data != NULL)) { |
| 2652 | ASSERT(ifp->if_real_bytes != 0); | 2591 | ASSERT(ifp->if_real_bytes != 0); |
| 2653 | kmem_free(ifp->if_u1.if_data, ifp->if_real_bytes); | 2592 | kmem_free(ifp->if_u1.if_data); |
| 2654 | ifp->if_u1.if_data = NULL; | 2593 | ifp->if_u1.if_data = NULL; |
| 2655 | ifp->if_real_bytes = 0; | 2594 | ifp->if_real_bytes = 0; |
| 2656 | } | 2595 | } |
| @@ -3058,7 +2997,7 @@ xfs_iflush_cluster( | |||
| 3058 | 2997 | ||
| 3059 | out_free: | 2998 | out_free: |
| 3060 | read_unlock(&pag->pag_ici_lock); | 2999 | read_unlock(&pag->pag_ici_lock); |
| 3061 | kmem_free(ilist, ilist_size); | 3000 | kmem_free(ilist); |
| 3062 | return 0; | 3001 | return 0; |
| 3063 | 3002 | ||
| 3064 | 3003 | ||
| @@ -3102,7 +3041,7 @@ cluster_corrupt_out: | |||
| 3102 | * Unlocks the flush lock | 3041 | * Unlocks the flush lock |
| 3103 | */ | 3042 | */ |
| 3104 | xfs_iflush_abort(iq); | 3043 | xfs_iflush_abort(iq); |
| 3105 | kmem_free(ilist, ilist_size); | 3044 | kmem_free(ilist); |
| 3106 | return XFS_ERROR(EFSCORRUPTED); | 3045 | return XFS_ERROR(EFSCORRUPTED); |
| 3107 | } | 3046 | } |
| 3108 | 3047 | ||
| @@ -3143,8 +3082,6 @@ xfs_iflush( | |||
| 3143 | * flush lock and do nothing. | 3082 | * flush lock and do nothing. |
| 3144 | */ | 3083 | */ |
| 3145 | if (xfs_inode_clean(ip)) { | 3084 | if (xfs_inode_clean(ip)) { |
| 3146 | ASSERT((iip != NULL) ? | ||
| 3147 | !(iip->ili_item.li_flags & XFS_LI_IN_AIL) : 1); | ||
| 3148 | xfs_ifunlock(ip); | 3085 | xfs_ifunlock(ip); |
| 3149 | return 0; | 3086 | return 0; |
| 3150 | } | 3087 | } |
| @@ -3836,7 +3773,7 @@ xfs_iext_add_indirect_multi( | |||
| 3836 | erp = xfs_iext_irec_new(ifp, erp_idx); | 3773 | erp = xfs_iext_irec_new(ifp, erp_idx); |
| 3837 | } | 3774 | } |
| 3838 | memmove(&erp->er_extbuf[i], nex2_ep, byte_diff); | 3775 | memmove(&erp->er_extbuf[i], nex2_ep, byte_diff); |
| 3839 | kmem_free(nex2_ep, byte_diff); | 3776 | kmem_free(nex2_ep); |
| 3840 | erp->er_extcount += nex2; | 3777 | erp->er_extcount += nex2; |
| 3841 | xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, nex2); | 3778 | xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, nex2); |
| 3842 | } | 3779 | } |
| @@ -4112,7 +4049,7 @@ xfs_iext_direct_to_inline( | |||
| 4112 | */ | 4049 | */ |
| 4113 | memcpy(ifp->if_u2.if_inline_ext, ifp->if_u1.if_extents, | 4050 | memcpy(ifp->if_u2.if_inline_ext, ifp->if_u1.if_extents, |
| 4114 | nextents * sizeof(xfs_bmbt_rec_t)); | 4051 | nextents * sizeof(xfs_bmbt_rec_t)); |
| 4115 | kmem_free(ifp->if_u1.if_extents, ifp->if_real_bytes); | 4052 | kmem_free(ifp->if_u1.if_extents); |
| 4116 | ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext; | 4053 | ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext; |
| 4117 | ifp->if_real_bytes = 0; | 4054 | ifp->if_real_bytes = 0; |
| 4118 | } | 4055 | } |
| @@ -4186,7 +4123,7 @@ xfs_iext_indirect_to_direct( | |||
| 4186 | ASSERT(ifp->if_real_bytes == XFS_IEXT_BUFSZ); | 4123 | ASSERT(ifp->if_real_bytes == XFS_IEXT_BUFSZ); |
| 4187 | 4124 | ||
| 4188 | ep = ifp->if_u1.if_ext_irec->er_extbuf; | 4125 | ep = ifp->if_u1.if_ext_irec->er_extbuf; |
| 4189 | kmem_free(ifp->if_u1.if_ext_irec, sizeof(xfs_ext_irec_t)); | 4126 | kmem_free(ifp->if_u1.if_ext_irec); |
| 4190 | ifp->if_flags &= ~XFS_IFEXTIREC; | 4127 | ifp->if_flags &= ~XFS_IFEXTIREC; |
| 4191 | ifp->if_u1.if_extents = ep; | 4128 | ifp->if_u1.if_extents = ep; |
| 4192 | ifp->if_bytes = size; | 4129 | ifp->if_bytes = size; |
| @@ -4212,7 +4149,7 @@ xfs_iext_destroy( | |||
| 4212 | } | 4149 | } |
| 4213 | ifp->if_flags &= ~XFS_IFEXTIREC; | 4150 | ifp->if_flags &= ~XFS_IFEXTIREC; |
| 4214 | } else if (ifp->if_real_bytes) { | 4151 | } else if (ifp->if_real_bytes) { |
| 4215 | kmem_free(ifp->if_u1.if_extents, ifp->if_real_bytes); | 4152 | kmem_free(ifp->if_u1.if_extents); |
| 4216 | } else if (ifp->if_bytes) { | 4153 | } else if (ifp->if_bytes) { |
| 4217 | memset(ifp->if_u2.if_inline_ext, 0, XFS_INLINE_EXTS * | 4154 | memset(ifp->if_u2.if_inline_ext, 0, XFS_INLINE_EXTS * |
| 4218 | sizeof(xfs_bmbt_rec_t)); | 4155 | sizeof(xfs_bmbt_rec_t)); |
| @@ -4483,7 +4420,7 @@ xfs_iext_irec_remove( | |||
| 4483 | if (erp->er_extbuf) { | 4420 | if (erp->er_extbuf) { |
| 4484 | xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, | 4421 | xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, |
| 4485 | -erp->er_extcount); | 4422 | -erp->er_extcount); |
| 4486 | kmem_free(erp->er_extbuf, XFS_IEXT_BUFSZ); | 4423 | kmem_free(erp->er_extbuf); |
| 4487 | } | 4424 | } |
| 4488 | /* Compact extent records */ | 4425 | /* Compact extent records */ |
| 4489 | erp = ifp->if_u1.if_ext_irec; | 4426 | erp = ifp->if_u1.if_ext_irec; |
| @@ -4501,8 +4438,7 @@ xfs_iext_irec_remove( | |||
| 4501 | xfs_iext_realloc_indirect(ifp, | 4438 | xfs_iext_realloc_indirect(ifp, |
| 4502 | nlists * sizeof(xfs_ext_irec_t)); | 4439 | nlists * sizeof(xfs_ext_irec_t)); |
| 4503 | } else { | 4440 | } else { |
| 4504 | kmem_free(ifp->if_u1.if_ext_irec, | 4441 | kmem_free(ifp->if_u1.if_ext_irec); |
| 4505 | sizeof(xfs_ext_irec_t)); | ||
| 4506 | } | 4442 | } |
| 4507 | ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ; | 4443 | ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ; |
| 4508 | } | 4444 | } |
| @@ -4571,7 +4507,7 @@ xfs_iext_irec_compact_pages( | |||
| 4571 | * so er_extoffs don't get modified in | 4507 | * so er_extoffs don't get modified in |
| 4572 | * xfs_iext_irec_remove. | 4508 | * xfs_iext_irec_remove. |
| 4573 | */ | 4509 | */ |
| 4574 | kmem_free(erp_next->er_extbuf, XFS_IEXT_BUFSZ); | 4510 | kmem_free(erp_next->er_extbuf); |
| 4575 | erp_next->er_extbuf = NULL; | 4511 | erp_next->er_extbuf = NULL; |
| 4576 | xfs_iext_irec_remove(ifp, erp_idx + 1); | 4512 | xfs_iext_irec_remove(ifp, erp_idx + 1); |
| 4577 | nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; | 4513 | nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; |
| @@ -4596,40 +4532,63 @@ xfs_iext_irec_compact_full( | |||
| 4596 | int nlists; /* number of irec's (ex lists) */ | 4532 | int nlists; /* number of irec's (ex lists) */ |
| 4597 | 4533 | ||
| 4598 | ASSERT(ifp->if_flags & XFS_IFEXTIREC); | 4534 | ASSERT(ifp->if_flags & XFS_IFEXTIREC); |
| 4535 | |||
| 4599 | nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; | 4536 | nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; |
| 4600 | erp = ifp->if_u1.if_ext_irec; | 4537 | erp = ifp->if_u1.if_ext_irec; |
| 4601 | ep = &erp->er_extbuf[erp->er_extcount]; | 4538 | ep = &erp->er_extbuf[erp->er_extcount]; |
| 4602 | erp_next = erp + 1; | 4539 | erp_next = erp + 1; |
| 4603 | ep_next = erp_next->er_extbuf; | 4540 | ep_next = erp_next->er_extbuf; |
| 4541 | |||
| 4604 | while (erp_idx < nlists - 1) { | 4542 | while (erp_idx < nlists - 1) { |
| 4543 | /* | ||
| 4544 | * Check how many extent records are available in this irec. | ||
| 4545 | * If there is none skip the whole exercise. | ||
| 4546 | */ | ||
| 4605 | ext_avail = XFS_LINEAR_EXTS - erp->er_extcount; | 4547 | ext_avail = XFS_LINEAR_EXTS - erp->er_extcount; |
| 4606 | ext_diff = MIN(ext_avail, erp_next->er_extcount); | 4548 | if (ext_avail) { |
| 4607 | memcpy(ep, ep_next, ext_diff * sizeof(xfs_bmbt_rec_t)); | 4549 | |
| 4608 | erp->er_extcount += ext_diff; | ||
| 4609 | erp_next->er_extcount -= ext_diff; | ||
| 4610 | /* Remove next page */ | ||
| 4611 | if (erp_next->er_extcount == 0) { | ||
| 4612 | /* | 4550 | /* |
| 4613 | * Free page before removing extent record | 4551 | * Copy over as many as possible extent records into |
| 4614 | * so er_extoffs don't get modified in | 4552 | * the previous page. |
| 4615 | * xfs_iext_irec_remove. | ||
| 4616 | */ | 4553 | */ |
| 4617 | kmem_free(erp_next->er_extbuf, | 4554 | ext_diff = MIN(ext_avail, erp_next->er_extcount); |
| 4618 | erp_next->er_extcount * sizeof(xfs_bmbt_rec_t)); | 4555 | memcpy(ep, ep_next, ext_diff * sizeof(xfs_bmbt_rec_t)); |
| 4619 | erp_next->er_extbuf = NULL; | 4556 | erp->er_extcount += ext_diff; |
| 4620 | xfs_iext_irec_remove(ifp, erp_idx + 1); | 4557 | erp_next->er_extcount -= ext_diff; |
| 4621 | erp = &ifp->if_u1.if_ext_irec[erp_idx]; | 4558 | |
| 4622 | nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; | 4559 | /* |
| 4623 | /* Update next page */ | 4560 | * If the next irec is empty now we can simply |
| 4624 | } else { | 4561 | * remove it. |
| 4625 | /* Move rest of page up to become next new page */ | 4562 | */ |
| 4626 | memmove(erp_next->er_extbuf, ep_next, | 4563 | if (erp_next->er_extcount == 0) { |
| 4627 | erp_next->er_extcount * sizeof(xfs_bmbt_rec_t)); | 4564 | /* |
| 4628 | ep_next = erp_next->er_extbuf; | 4565 | * Free page before removing extent record |
| 4629 | memset(&ep_next[erp_next->er_extcount], 0, | 4566 | * so er_extoffs don't get modified in |
| 4630 | (XFS_LINEAR_EXTS - erp_next->er_extcount) * | 4567 | * xfs_iext_irec_remove. |
| 4631 | sizeof(xfs_bmbt_rec_t)); | 4568 | */ |
| 4569 | kmem_free(erp_next->er_extbuf); | ||
| 4570 | erp_next->er_extbuf = NULL; | ||
| 4571 | xfs_iext_irec_remove(ifp, erp_idx + 1); | ||
| 4572 | erp = &ifp->if_u1.if_ext_irec[erp_idx]; | ||
| 4573 | nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; | ||
| 4574 | |||
| 4575 | /* | ||
| 4576 | * If the next irec is not empty move up the content | ||
| 4577 | * that has not been copied to the previous page to | ||
| 4578 | * the beggining of this one. | ||
| 4579 | */ | ||
| 4580 | } else { | ||
| 4581 | memmove(erp_next->er_extbuf, &ep_next[ext_diff], | ||
| 4582 | erp_next->er_extcount * | ||
| 4583 | sizeof(xfs_bmbt_rec_t)); | ||
| 4584 | ep_next = erp_next->er_extbuf; | ||
| 4585 | memset(&ep_next[erp_next->er_extcount], 0, | ||
| 4586 | (XFS_LINEAR_EXTS - | ||
| 4587 | erp_next->er_extcount) * | ||
| 4588 | sizeof(xfs_bmbt_rec_t)); | ||
| 4589 | } | ||
| 4632 | } | 4590 | } |
| 4591 | |||
| 4633 | if (erp->er_extcount == XFS_LINEAR_EXTS) { | 4592 | if (erp->er_extcount == XFS_LINEAR_EXTS) { |
| 4634 | erp_idx++; | 4593 | erp_idx++; |
| 4635 | if (erp_idx < nlists) | 4594 | if (erp_idx < nlists) |
