diff options
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r-- | fs/xfs/xfs_inode.c | 235 |
1 files changed, 96 insertions, 139 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index e569bf5d6cf0..00e80df9dd9d 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -580,8 +580,8 @@ xfs_iformat_extents( | |||
580 | xfs_validate_extents(ifp, nex, XFS_EXTFMT_INODE(ip)); | 580 | xfs_validate_extents(ifp, nex, XFS_EXTFMT_INODE(ip)); |
581 | for (i = 0; i < nex; i++, dp++) { | 581 | for (i = 0; i < nex; i++, dp++) { |
582 | xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i); | 582 | xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i); |
583 | ep->l0 = be64_to_cpu(get_unaligned(&dp->l0)); | 583 | ep->l0 = get_unaligned_be64(&dp->l0); |
584 | ep->l1 = be64_to_cpu(get_unaligned(&dp->l1)); | 584 | ep->l1 = get_unaligned_be64(&dp->l1); |
585 | } | 585 | } |
586 | XFS_BMAP_TRACE_EXLIST(ip, nex, whichfork); | 586 | XFS_BMAP_TRACE_EXLIST(ip, nex, whichfork); |
587 | if (whichfork != XFS_DATA_FORK || | 587 | if (whichfork != XFS_DATA_FORK || |
@@ -835,22 +835,22 @@ xfs_iread( | |||
835 | * Do this before xfs_iformat in case it adds entries. | 835 | * Do this before xfs_iformat in case it adds entries. |
836 | */ | 836 | */ |
837 | #ifdef XFS_INODE_TRACE | 837 | #ifdef XFS_INODE_TRACE |
838 | ip->i_trace = ktrace_alloc(INODE_TRACE_SIZE, KM_SLEEP); | 838 | ip->i_trace = ktrace_alloc(INODE_TRACE_SIZE, KM_NOFS); |
839 | #endif | 839 | #endif |
840 | #ifdef XFS_BMAP_TRACE | 840 | #ifdef XFS_BMAP_TRACE |
841 | ip->i_xtrace = ktrace_alloc(XFS_BMAP_KTRACE_SIZE, KM_SLEEP); | 841 | ip->i_xtrace = ktrace_alloc(XFS_BMAP_KTRACE_SIZE, KM_NOFS); |
842 | #endif | 842 | #endif |
843 | #ifdef XFS_BMBT_TRACE | 843 | #ifdef XFS_BMBT_TRACE |
844 | ip->i_btrace = ktrace_alloc(XFS_BMBT_KTRACE_SIZE, KM_SLEEP); | 844 | ip->i_btrace = ktrace_alloc(XFS_BMBT_KTRACE_SIZE, KM_NOFS); |
845 | #endif | 845 | #endif |
846 | #ifdef XFS_RW_TRACE | 846 | #ifdef XFS_RW_TRACE |
847 | ip->i_rwtrace = ktrace_alloc(XFS_RW_KTRACE_SIZE, KM_SLEEP); | 847 | ip->i_rwtrace = ktrace_alloc(XFS_RW_KTRACE_SIZE, KM_NOFS); |
848 | #endif | 848 | #endif |
849 | #ifdef XFS_ILOCK_TRACE | 849 | #ifdef XFS_ILOCK_TRACE |
850 | ip->i_lock_trace = ktrace_alloc(XFS_ILOCK_KTRACE_SIZE, KM_SLEEP); | 850 | ip->i_lock_trace = ktrace_alloc(XFS_ILOCK_KTRACE_SIZE, KM_NOFS); |
851 | #endif | 851 | #endif |
852 | #ifdef XFS_DIR2_TRACE | 852 | #ifdef XFS_DIR2_TRACE |
853 | ip->i_dir_trace = ktrace_alloc(XFS_DIR2_KTRACE_SIZE, KM_SLEEP); | 853 | ip->i_dir_trace = ktrace_alloc(XFS_DIR2_KTRACE_SIZE, KM_NOFS); |
854 | #endif | 854 | #endif |
855 | 855 | ||
856 | /* | 856 | /* |
@@ -1046,9 +1046,9 @@ xfs_ialloc( | |||
1046 | { | 1046 | { |
1047 | xfs_ino_t ino; | 1047 | xfs_ino_t ino; |
1048 | xfs_inode_t *ip; | 1048 | xfs_inode_t *ip; |
1049 | bhv_vnode_t *vp; | ||
1050 | uint flags; | 1049 | uint flags; |
1051 | int error; | 1050 | int error; |
1051 | timespec_t tv; | ||
1052 | 1052 | ||
1053 | /* | 1053 | /* |
1054 | * Call the space management code to pick | 1054 | * Call the space management code to pick |
@@ -1077,13 +1077,12 @@ xfs_ialloc( | |||
1077 | } | 1077 | } |
1078 | ASSERT(ip != NULL); | 1078 | ASSERT(ip != NULL); |
1079 | 1079 | ||
1080 | vp = XFS_ITOV(ip); | ||
1081 | ip->i_d.di_mode = (__uint16_t)mode; | 1080 | ip->i_d.di_mode = (__uint16_t)mode; |
1082 | ip->i_d.di_onlink = 0; | 1081 | ip->i_d.di_onlink = 0; |
1083 | ip->i_d.di_nlink = nlink; | 1082 | ip->i_d.di_nlink = nlink; |
1084 | ASSERT(ip->i_d.di_nlink == nlink); | 1083 | ASSERT(ip->i_d.di_nlink == nlink); |
1085 | ip->i_d.di_uid = current_fsuid(cr); | 1084 | ip->i_d.di_uid = current_fsuid(); |
1086 | ip->i_d.di_gid = current_fsgid(cr); | 1085 | ip->i_d.di_gid = current_fsgid(); |
1087 | ip->i_d.di_projid = prid; | 1086 | ip->i_d.di_projid = prid; |
1088 | memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); | 1087 | memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); |
1089 | 1088 | ||
@@ -1130,7 +1129,13 @@ xfs_ialloc( | |||
1130 | ip->i_size = 0; | 1129 | ip->i_size = 0; |
1131 | ip->i_d.di_nextents = 0; | 1130 | ip->i_d.di_nextents = 0; |
1132 | ASSERT(ip->i_d.di_nblocks == 0); | 1131 | ASSERT(ip->i_d.di_nblocks == 0); |
1133 | xfs_ichgtime(ip, XFS_ICHGTIME_CHG|XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD); | 1132 | |
1133 | nanotime(&tv); | ||
1134 | ip->i_d.di_mtime.t_sec = (__int32_t)tv.tv_sec; | ||
1135 | ip->i_d.di_mtime.t_nsec = (__int32_t)tv.tv_nsec; | ||
1136 | ip->i_d.di_atime = ip->i_d.di_mtime; | ||
1137 | ip->i_d.di_ctime = ip->i_d.di_mtime; | ||
1138 | |||
1134 | /* | 1139 | /* |
1135 | * di_gen will have been taken care of in xfs_iread. | 1140 | * di_gen will have been taken care of in xfs_iread. |
1136 | */ | 1141 | */ |
@@ -1220,7 +1225,7 @@ xfs_ialloc( | |||
1220 | xfs_trans_log_inode(tp, ip, flags); | 1225 | xfs_trans_log_inode(tp, ip, flags); |
1221 | 1226 | ||
1222 | /* now that we have an i_mode we can setup inode ops and unlock */ | 1227 | /* now that we have an i_mode we can setup inode ops and unlock */ |
1223 | xfs_initialize_vnode(tp->t_mountp, vp, ip); | 1228 | xfs_setup_inode(ip); |
1224 | 1229 | ||
1225 | *ipp = ip; | 1230 | *ipp = ip; |
1226 | return 0; | 1231 | return 0; |
@@ -1399,7 +1404,6 @@ xfs_itruncate_start( | |||
1399 | xfs_fsize_t last_byte; | 1404 | xfs_fsize_t last_byte; |
1400 | xfs_off_t toss_start; | 1405 | xfs_off_t toss_start; |
1401 | xfs_mount_t *mp; | 1406 | xfs_mount_t *mp; |
1402 | bhv_vnode_t *vp; | ||
1403 | int error = 0; | 1407 | int error = 0; |
1404 | 1408 | ||
1405 | ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); | 1409 | ASSERT(xfs_isilocked(ip, XFS_IOLOCK_EXCL)); |
@@ -1408,7 +1412,6 @@ xfs_itruncate_start( | |||
1408 | (flags == XFS_ITRUNC_MAYBE)); | 1412 | (flags == XFS_ITRUNC_MAYBE)); |
1409 | 1413 | ||
1410 | mp = ip->i_mount; | 1414 | mp = ip->i_mount; |
1411 | vp = XFS_ITOV(ip); | ||
1412 | 1415 | ||
1413 | /* wait for the completion of any pending DIOs */ | 1416 | /* wait for the completion of any pending DIOs */ |
1414 | if (new_size < ip->i_size) | 1417 | if (new_size < ip->i_size) |
@@ -1457,7 +1460,7 @@ xfs_itruncate_start( | |||
1457 | 1460 | ||
1458 | #ifdef DEBUG | 1461 | #ifdef DEBUG |
1459 | if (new_size == 0) { | 1462 | if (new_size == 0) { |
1460 | ASSERT(VN_CACHED(vp) == 0); | 1463 | ASSERT(VN_CACHED(VFS_I(ip)) == 0); |
1461 | } | 1464 | } |
1462 | #endif | 1465 | #endif |
1463 | return error; | 1466 | return error; |
@@ -1763,67 +1766,6 @@ xfs_itruncate_finish( | |||
1763 | return 0; | 1766 | return 0; |
1764 | } | 1767 | } |
1765 | 1768 | ||
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 | /* | 1769 | /* |
1828 | * This is called when the inode's link count goes to 0. | 1770 | * 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 | 1771 | * We place the on-disk inode on a list in the AGI. It |
@@ -2258,7 +2200,7 @@ xfs_ifree_cluster( | |||
2258 | xfs_trans_binval(tp, bp); | 2200 | xfs_trans_binval(tp, bp); |
2259 | } | 2201 | } |
2260 | 2202 | ||
2261 | kmem_free(ip_found, ninodes * sizeof(xfs_inode_t *)); | 2203 | kmem_free(ip_found); |
2262 | xfs_put_perag(mp, pag); | 2204 | xfs_put_perag(mp, pag); |
2263 | } | 2205 | } |
2264 | 2206 | ||
@@ -2470,7 +2412,7 @@ xfs_iroot_realloc( | |||
2470 | (int)new_size); | 2412 | (int)new_size); |
2471 | memcpy(np, op, new_max * (uint)sizeof(xfs_dfsbno_t)); | 2413 | memcpy(np, op, new_max * (uint)sizeof(xfs_dfsbno_t)); |
2472 | } | 2414 | } |
2473 | kmem_free(ifp->if_broot, ifp->if_broot_bytes); | 2415 | kmem_free(ifp->if_broot); |
2474 | ifp->if_broot = new_broot; | 2416 | ifp->if_broot = new_broot; |
2475 | ifp->if_broot_bytes = (int)new_size; | 2417 | ifp->if_broot_bytes = (int)new_size; |
2476 | ASSERT(ifp->if_broot_bytes <= | 2418 | ASSERT(ifp->if_broot_bytes <= |
@@ -2514,7 +2456,7 @@ xfs_idata_realloc( | |||
2514 | 2456 | ||
2515 | if (new_size == 0) { | 2457 | if (new_size == 0) { |
2516 | if (ifp->if_u1.if_data != ifp->if_u2.if_inline_data) { | 2458 | if (ifp->if_u1.if_data != ifp->if_u2.if_inline_data) { |
2517 | kmem_free(ifp->if_u1.if_data, ifp->if_real_bytes); | 2459 | kmem_free(ifp->if_u1.if_data); |
2518 | } | 2460 | } |
2519 | ifp->if_u1.if_data = NULL; | 2461 | ifp->if_u1.if_data = NULL; |
2520 | real_size = 0; | 2462 | real_size = 0; |
@@ -2529,7 +2471,7 @@ xfs_idata_realloc( | |||
2529 | ASSERT(ifp->if_real_bytes != 0); | 2471 | ASSERT(ifp->if_real_bytes != 0); |
2530 | memcpy(ifp->if_u2.if_inline_data, ifp->if_u1.if_data, | 2472 | memcpy(ifp->if_u2.if_inline_data, ifp->if_u1.if_data, |
2531 | new_size); | 2473 | new_size); |
2532 | kmem_free(ifp->if_u1.if_data, ifp->if_real_bytes); | 2474 | kmem_free(ifp->if_u1.if_data); |
2533 | ifp->if_u1.if_data = ifp->if_u2.if_inline_data; | 2475 | ifp->if_u1.if_data = ifp->if_u2.if_inline_data; |
2534 | } | 2476 | } |
2535 | real_size = 0; | 2477 | real_size = 0; |
@@ -2636,7 +2578,7 @@ xfs_idestroy_fork( | |||
2636 | 2578 | ||
2637 | ifp = XFS_IFORK_PTR(ip, whichfork); | 2579 | ifp = XFS_IFORK_PTR(ip, whichfork); |
2638 | if (ifp->if_broot != NULL) { | 2580 | if (ifp->if_broot != NULL) { |
2639 | kmem_free(ifp->if_broot, ifp->if_broot_bytes); | 2581 | kmem_free(ifp->if_broot); |
2640 | ifp->if_broot = NULL; | 2582 | ifp->if_broot = NULL; |
2641 | } | 2583 | } |
2642 | 2584 | ||
@@ -2650,7 +2592,7 @@ xfs_idestroy_fork( | |||
2650 | if ((ifp->if_u1.if_data != ifp->if_u2.if_inline_data) && | 2592 | if ((ifp->if_u1.if_data != ifp->if_u2.if_inline_data) && |
2651 | (ifp->if_u1.if_data != NULL)) { | 2593 | (ifp->if_u1.if_data != NULL)) { |
2652 | ASSERT(ifp->if_real_bytes != 0); | 2594 | ASSERT(ifp->if_real_bytes != 0); |
2653 | kmem_free(ifp->if_u1.if_data, ifp->if_real_bytes); | 2595 | kmem_free(ifp->if_u1.if_data); |
2654 | ifp->if_u1.if_data = NULL; | 2596 | ifp->if_u1.if_data = NULL; |
2655 | ifp->if_real_bytes = 0; | 2597 | ifp->if_real_bytes = 0; |
2656 | } | 2598 | } |
@@ -2691,7 +2633,6 @@ xfs_idestroy( | |||
2691 | xfs_idestroy_fork(ip, XFS_ATTR_FORK); | 2633 | xfs_idestroy_fork(ip, XFS_ATTR_FORK); |
2692 | mrfree(&ip->i_lock); | 2634 | mrfree(&ip->i_lock); |
2693 | mrfree(&ip->i_iolock); | 2635 | mrfree(&ip->i_iolock); |
2694 | freesema(&ip->i_flock); | ||
2695 | 2636 | ||
2696 | #ifdef XFS_INODE_TRACE | 2637 | #ifdef XFS_INODE_TRACE |
2697 | ktrace_free(ip->i_trace); | 2638 | ktrace_free(ip->i_trace); |
@@ -3058,7 +2999,7 @@ xfs_iflush_cluster( | |||
3058 | 2999 | ||
3059 | out_free: | 3000 | out_free: |
3060 | read_unlock(&pag->pag_ici_lock); | 3001 | read_unlock(&pag->pag_ici_lock); |
3061 | kmem_free(ilist, ilist_size); | 3002 | kmem_free(ilist); |
3062 | return 0; | 3003 | return 0; |
3063 | 3004 | ||
3064 | 3005 | ||
@@ -3102,17 +3043,17 @@ cluster_corrupt_out: | |||
3102 | * Unlocks the flush lock | 3043 | * Unlocks the flush lock |
3103 | */ | 3044 | */ |
3104 | xfs_iflush_abort(iq); | 3045 | xfs_iflush_abort(iq); |
3105 | kmem_free(ilist, ilist_size); | 3046 | kmem_free(ilist); |
3106 | return XFS_ERROR(EFSCORRUPTED); | 3047 | return XFS_ERROR(EFSCORRUPTED); |
3107 | } | 3048 | } |
3108 | 3049 | ||
3109 | /* | 3050 | /* |
3110 | * xfs_iflush() will write a modified inode's changes out to the | 3051 | * xfs_iflush() will write a modified inode's changes out to the |
3111 | * inode's on disk home. The caller must have the inode lock held | 3052 | * inode's on disk home. The caller must have the inode lock held |
3112 | * in at least shared mode and the inode flush semaphore must be | 3053 | * in at least shared mode and the inode flush completion must be |
3113 | * held as well. The inode lock will still be held upon return from | 3054 | * active as well. The inode lock will still be held upon return from |
3114 | * the call and the caller is free to unlock it. | 3055 | * the call and the caller is free to unlock it. |
3115 | * The inode flush lock will be unlocked when the inode reaches the disk. | 3056 | * The inode flush will be completed when the inode reaches the disk. |
3116 | * The flags indicate how the inode's buffer should be written out. | 3057 | * The flags indicate how the inode's buffer should be written out. |
3117 | */ | 3058 | */ |
3118 | int | 3059 | int |
@@ -3131,7 +3072,7 @@ xfs_iflush( | |||
3131 | XFS_STATS_INC(xs_iflush_count); | 3072 | XFS_STATS_INC(xs_iflush_count); |
3132 | 3073 | ||
3133 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); | 3074 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); |
3134 | ASSERT(issemalocked(&(ip->i_flock))); | 3075 | ASSERT(!completion_done(&ip->i_flush)); |
3135 | ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || | 3076 | ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || |
3136 | ip->i_d.di_nextents > ip->i_df.if_ext_max); | 3077 | ip->i_d.di_nextents > ip->i_df.if_ext_max); |
3137 | 3078 | ||
@@ -3143,8 +3084,6 @@ xfs_iflush( | |||
3143 | * flush lock and do nothing. | 3084 | * flush lock and do nothing. |
3144 | */ | 3085 | */ |
3145 | if (xfs_inode_clean(ip)) { | 3086 | if (xfs_inode_clean(ip)) { |
3146 | ASSERT((iip != NULL) ? | ||
3147 | !(iip->ili_item.li_flags & XFS_LI_IN_AIL) : 1); | ||
3148 | xfs_ifunlock(ip); | 3087 | xfs_ifunlock(ip); |
3149 | return 0; | 3088 | return 0; |
3150 | } | 3089 | } |
@@ -3296,7 +3235,7 @@ xfs_iflush_int( | |||
3296 | #endif | 3235 | #endif |
3297 | 3236 | ||
3298 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); | 3237 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); |
3299 | ASSERT(issemalocked(&(ip->i_flock))); | 3238 | ASSERT(!completion_done(&ip->i_flush)); |
3300 | ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || | 3239 | ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || |
3301 | ip->i_d.di_nextents > ip->i_df.if_ext_max); | 3240 | ip->i_d.di_nextents > ip->i_df.if_ext_max); |
3302 | 3241 | ||
@@ -3528,7 +3467,6 @@ xfs_iflush_all( | |||
3528 | xfs_mount_t *mp) | 3467 | xfs_mount_t *mp) |
3529 | { | 3468 | { |
3530 | xfs_inode_t *ip; | 3469 | xfs_inode_t *ip; |
3531 | bhv_vnode_t *vp; | ||
3532 | 3470 | ||
3533 | again: | 3471 | again: |
3534 | XFS_MOUNT_ILOCK(mp); | 3472 | XFS_MOUNT_ILOCK(mp); |
@@ -3543,14 +3481,13 @@ xfs_iflush_all( | |||
3543 | continue; | 3481 | continue; |
3544 | } | 3482 | } |
3545 | 3483 | ||
3546 | vp = XFS_ITOV_NULL(ip); | 3484 | if (!VFS_I(ip)) { |
3547 | if (!vp) { | ||
3548 | XFS_MOUNT_IUNLOCK(mp); | 3485 | XFS_MOUNT_IUNLOCK(mp); |
3549 | xfs_finish_reclaim(ip, 0, XFS_IFLUSH_ASYNC); | 3486 | xfs_finish_reclaim(ip, 0, XFS_IFLUSH_ASYNC); |
3550 | goto again; | 3487 | goto again; |
3551 | } | 3488 | } |
3552 | 3489 | ||
3553 | ASSERT(vn_count(vp) == 0); | 3490 | ASSERT(vn_count(VFS_I(ip)) == 0); |
3554 | 3491 | ||
3555 | ip = ip->i_mnext; | 3492 | ip = ip->i_mnext; |
3556 | } while (ip != mp->m_inodes); | 3493 | } while (ip != mp->m_inodes); |
@@ -3770,7 +3707,7 @@ xfs_iext_add_indirect_multi( | |||
3770 | * (all extents past */ | 3707 | * (all extents past */ |
3771 | if (nex2) { | 3708 | if (nex2) { |
3772 | byte_diff = nex2 * sizeof(xfs_bmbt_rec_t); | 3709 | byte_diff = nex2 * sizeof(xfs_bmbt_rec_t); |
3773 | nex2_ep = (xfs_bmbt_rec_t *) kmem_alloc(byte_diff, KM_SLEEP); | 3710 | nex2_ep = (xfs_bmbt_rec_t *) kmem_alloc(byte_diff, KM_NOFS); |
3774 | memmove(nex2_ep, &erp->er_extbuf[idx], byte_diff); | 3711 | memmove(nex2_ep, &erp->er_extbuf[idx], byte_diff); |
3775 | erp->er_extcount -= nex2; | 3712 | erp->er_extcount -= nex2; |
3776 | xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, -nex2); | 3713 | xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, -nex2); |
@@ -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 | } |
@@ -4070,8 +4007,7 @@ xfs_iext_realloc_direct( | |||
4070 | ifp->if_u1.if_extents = | 4007 | ifp->if_u1.if_extents = |
4071 | kmem_realloc(ifp->if_u1.if_extents, | 4008 | kmem_realloc(ifp->if_u1.if_extents, |
4072 | rnew_size, | 4009 | rnew_size, |
4073 | ifp->if_real_bytes, | 4010 | ifp->if_real_bytes, KM_NOFS); |
4074 | KM_SLEEP); | ||
4075 | } | 4011 | } |
4076 | if (rnew_size > ifp->if_real_bytes) { | 4012 | if (rnew_size > ifp->if_real_bytes) { |
4077 | memset(&ifp->if_u1.if_extents[ifp->if_bytes / | 4013 | memset(&ifp->if_u1.if_extents[ifp->if_bytes / |
@@ -4112,7 +4048,7 @@ xfs_iext_direct_to_inline( | |||
4112 | */ | 4048 | */ |
4113 | memcpy(ifp->if_u2.if_inline_ext, ifp->if_u1.if_extents, | 4049 | memcpy(ifp->if_u2.if_inline_ext, ifp->if_u1.if_extents, |
4114 | nextents * sizeof(xfs_bmbt_rec_t)); | 4050 | nextents * sizeof(xfs_bmbt_rec_t)); |
4115 | kmem_free(ifp->if_u1.if_extents, ifp->if_real_bytes); | 4051 | kmem_free(ifp->if_u1.if_extents); |
4116 | ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext; | 4052 | ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext; |
4117 | ifp->if_real_bytes = 0; | 4053 | ifp->if_real_bytes = 0; |
4118 | } | 4054 | } |
@@ -4130,7 +4066,7 @@ xfs_iext_inline_to_direct( | |||
4130 | xfs_ifork_t *ifp, /* inode fork pointer */ | 4066 | xfs_ifork_t *ifp, /* inode fork pointer */ |
4131 | int new_size) /* number of extents in file */ | 4067 | int new_size) /* number of extents in file */ |
4132 | { | 4068 | { |
4133 | ifp->if_u1.if_extents = kmem_alloc(new_size, KM_SLEEP); | 4069 | ifp->if_u1.if_extents = kmem_alloc(new_size, KM_NOFS); |
4134 | memset(ifp->if_u1.if_extents, 0, new_size); | 4070 | memset(ifp->if_u1.if_extents, 0, new_size); |
4135 | if (ifp->if_bytes) { | 4071 | if (ifp->if_bytes) { |
4136 | memcpy(ifp->if_u1.if_extents, ifp->if_u2.if_inline_ext, | 4072 | memcpy(ifp->if_u1.if_extents, ifp->if_u2.if_inline_ext, |
@@ -4162,7 +4098,7 @@ xfs_iext_realloc_indirect( | |||
4162 | } else { | 4098 | } else { |
4163 | ifp->if_u1.if_ext_irec = (xfs_ext_irec_t *) | 4099 | ifp->if_u1.if_ext_irec = (xfs_ext_irec_t *) |
4164 | kmem_realloc(ifp->if_u1.if_ext_irec, | 4100 | kmem_realloc(ifp->if_u1.if_ext_irec, |
4165 | new_size, size, KM_SLEEP); | 4101 | new_size, size, KM_NOFS); |
4166 | } | 4102 | } |
4167 | } | 4103 | } |
4168 | 4104 | ||
@@ -4186,7 +4122,7 @@ xfs_iext_indirect_to_direct( | |||
4186 | ASSERT(ifp->if_real_bytes == XFS_IEXT_BUFSZ); | 4122 | ASSERT(ifp->if_real_bytes == XFS_IEXT_BUFSZ); |
4187 | 4123 | ||
4188 | ep = ifp->if_u1.if_ext_irec->er_extbuf; | 4124 | ep = ifp->if_u1.if_ext_irec->er_extbuf; |
4189 | kmem_free(ifp->if_u1.if_ext_irec, sizeof(xfs_ext_irec_t)); | 4125 | kmem_free(ifp->if_u1.if_ext_irec); |
4190 | ifp->if_flags &= ~XFS_IFEXTIREC; | 4126 | ifp->if_flags &= ~XFS_IFEXTIREC; |
4191 | ifp->if_u1.if_extents = ep; | 4127 | ifp->if_u1.if_extents = ep; |
4192 | ifp->if_bytes = size; | 4128 | ifp->if_bytes = size; |
@@ -4212,7 +4148,7 @@ xfs_iext_destroy( | |||
4212 | } | 4148 | } |
4213 | ifp->if_flags &= ~XFS_IFEXTIREC; | 4149 | ifp->if_flags &= ~XFS_IFEXTIREC; |
4214 | } else if (ifp->if_real_bytes) { | 4150 | } else if (ifp->if_real_bytes) { |
4215 | kmem_free(ifp->if_u1.if_extents, ifp->if_real_bytes); | 4151 | kmem_free(ifp->if_u1.if_extents); |
4216 | } else if (ifp->if_bytes) { | 4152 | } else if (ifp->if_bytes) { |
4217 | memset(ifp->if_u2.if_inline_ext, 0, XFS_INLINE_EXTS * | 4153 | memset(ifp->if_u2.if_inline_ext, 0, XFS_INLINE_EXTS * |
4218 | sizeof(xfs_bmbt_rec_t)); | 4154 | sizeof(xfs_bmbt_rec_t)); |
@@ -4404,11 +4340,10 @@ xfs_iext_irec_init( | |||
4404 | nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); | 4340 | nextents = ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t); |
4405 | ASSERT(nextents <= XFS_LINEAR_EXTS); | 4341 | ASSERT(nextents <= XFS_LINEAR_EXTS); |
4406 | 4342 | ||
4407 | erp = (xfs_ext_irec_t *) | 4343 | erp = kmem_alloc(sizeof(xfs_ext_irec_t), KM_NOFS); |
4408 | kmem_alloc(sizeof(xfs_ext_irec_t), KM_SLEEP); | ||
4409 | 4344 | ||
4410 | if (nextents == 0) { | 4345 | if (nextents == 0) { |
4411 | ifp->if_u1.if_extents = kmem_alloc(XFS_IEXT_BUFSZ, KM_SLEEP); | 4346 | ifp->if_u1.if_extents = kmem_alloc(XFS_IEXT_BUFSZ, KM_NOFS); |
4412 | } else if (!ifp->if_real_bytes) { | 4347 | } else if (!ifp->if_real_bytes) { |
4413 | xfs_iext_inline_to_direct(ifp, XFS_IEXT_BUFSZ); | 4348 | xfs_iext_inline_to_direct(ifp, XFS_IEXT_BUFSZ); |
4414 | } else if (ifp->if_real_bytes < XFS_IEXT_BUFSZ) { | 4349 | } else if (ifp->if_real_bytes < XFS_IEXT_BUFSZ) { |
@@ -4456,7 +4391,7 @@ xfs_iext_irec_new( | |||
4456 | 4391 | ||
4457 | /* Initialize new extent record */ | 4392 | /* Initialize new extent record */ |
4458 | erp = ifp->if_u1.if_ext_irec; | 4393 | erp = ifp->if_u1.if_ext_irec; |
4459 | erp[erp_idx].er_extbuf = kmem_alloc(XFS_IEXT_BUFSZ, KM_SLEEP); | 4394 | erp[erp_idx].er_extbuf = kmem_alloc(XFS_IEXT_BUFSZ, KM_NOFS); |
4460 | ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ; | 4395 | ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ; |
4461 | memset(erp[erp_idx].er_extbuf, 0, XFS_IEXT_BUFSZ); | 4396 | memset(erp[erp_idx].er_extbuf, 0, XFS_IEXT_BUFSZ); |
4462 | erp[erp_idx].er_extcount = 0; | 4397 | erp[erp_idx].er_extcount = 0; |
@@ -4483,7 +4418,7 @@ xfs_iext_irec_remove( | |||
4483 | if (erp->er_extbuf) { | 4418 | if (erp->er_extbuf) { |
4484 | xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, | 4419 | xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, |
4485 | -erp->er_extcount); | 4420 | -erp->er_extcount); |
4486 | kmem_free(erp->er_extbuf, XFS_IEXT_BUFSZ); | 4421 | kmem_free(erp->er_extbuf); |
4487 | } | 4422 | } |
4488 | /* Compact extent records */ | 4423 | /* Compact extent records */ |
4489 | erp = ifp->if_u1.if_ext_irec; | 4424 | erp = ifp->if_u1.if_ext_irec; |
@@ -4501,8 +4436,7 @@ xfs_iext_irec_remove( | |||
4501 | xfs_iext_realloc_indirect(ifp, | 4436 | xfs_iext_realloc_indirect(ifp, |
4502 | nlists * sizeof(xfs_ext_irec_t)); | 4437 | nlists * sizeof(xfs_ext_irec_t)); |
4503 | } else { | 4438 | } else { |
4504 | kmem_free(ifp->if_u1.if_ext_irec, | 4439 | kmem_free(ifp->if_u1.if_ext_irec); |
4505 | sizeof(xfs_ext_irec_t)); | ||
4506 | } | 4440 | } |
4507 | ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ; | 4441 | ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ; |
4508 | } | 4442 | } |
@@ -4571,7 +4505,7 @@ xfs_iext_irec_compact_pages( | |||
4571 | * so er_extoffs don't get modified in | 4505 | * so er_extoffs don't get modified in |
4572 | * xfs_iext_irec_remove. | 4506 | * xfs_iext_irec_remove. |
4573 | */ | 4507 | */ |
4574 | kmem_free(erp_next->er_extbuf, XFS_IEXT_BUFSZ); | 4508 | kmem_free(erp_next->er_extbuf); |
4575 | erp_next->er_extbuf = NULL; | 4509 | erp_next->er_extbuf = NULL; |
4576 | xfs_iext_irec_remove(ifp, erp_idx + 1); | 4510 | xfs_iext_irec_remove(ifp, erp_idx + 1); |
4577 | nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; | 4511 | nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; |
@@ -4596,40 +4530,63 @@ xfs_iext_irec_compact_full( | |||
4596 | int nlists; /* number of irec's (ex lists) */ | 4530 | int nlists; /* number of irec's (ex lists) */ |
4597 | 4531 | ||
4598 | ASSERT(ifp->if_flags & XFS_IFEXTIREC); | 4532 | ASSERT(ifp->if_flags & XFS_IFEXTIREC); |
4533 | |||
4599 | nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; | 4534 | nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; |
4600 | erp = ifp->if_u1.if_ext_irec; | 4535 | erp = ifp->if_u1.if_ext_irec; |
4601 | ep = &erp->er_extbuf[erp->er_extcount]; | 4536 | ep = &erp->er_extbuf[erp->er_extcount]; |
4602 | erp_next = erp + 1; | 4537 | erp_next = erp + 1; |
4603 | ep_next = erp_next->er_extbuf; | 4538 | ep_next = erp_next->er_extbuf; |
4539 | |||
4604 | while (erp_idx < nlists - 1) { | 4540 | while (erp_idx < nlists - 1) { |
4541 | /* | ||
4542 | * Check how many extent records are available in this irec. | ||
4543 | * If there is none skip the whole exercise. | ||
4544 | */ | ||
4605 | ext_avail = XFS_LINEAR_EXTS - erp->er_extcount; | 4545 | ext_avail = XFS_LINEAR_EXTS - erp->er_extcount; |
4606 | ext_diff = MIN(ext_avail, erp_next->er_extcount); | 4546 | if (ext_avail) { |
4607 | memcpy(ep, ep_next, ext_diff * sizeof(xfs_bmbt_rec_t)); | 4547 | |
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 | /* | 4548 | /* |
4613 | * Free page before removing extent record | 4549 | * Copy over as many as possible extent records into |
4614 | * so er_extoffs don't get modified in | 4550 | * the previous page. |
4615 | * xfs_iext_irec_remove. | ||
4616 | */ | 4551 | */ |
4617 | kmem_free(erp_next->er_extbuf, | 4552 | ext_diff = MIN(ext_avail, erp_next->er_extcount); |
4618 | erp_next->er_extcount * sizeof(xfs_bmbt_rec_t)); | 4553 | memcpy(ep, ep_next, ext_diff * sizeof(xfs_bmbt_rec_t)); |
4619 | erp_next->er_extbuf = NULL; | 4554 | erp->er_extcount += ext_diff; |
4620 | xfs_iext_irec_remove(ifp, erp_idx + 1); | 4555 | erp_next->er_extcount -= ext_diff; |
4621 | erp = &ifp->if_u1.if_ext_irec[erp_idx]; | 4556 | |
4622 | nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; | 4557 | /* |
4623 | /* Update next page */ | 4558 | * If the next irec is empty now we can simply |
4624 | } else { | 4559 | * remove it. |
4625 | /* Move rest of page up to become next new page */ | 4560 | */ |
4626 | memmove(erp_next->er_extbuf, ep_next, | 4561 | if (erp_next->er_extcount == 0) { |
4627 | erp_next->er_extcount * sizeof(xfs_bmbt_rec_t)); | 4562 | /* |
4628 | ep_next = erp_next->er_extbuf; | 4563 | * Free page before removing extent record |
4629 | memset(&ep_next[erp_next->er_extcount], 0, | 4564 | * so er_extoffs don't get modified in |
4630 | (XFS_LINEAR_EXTS - erp_next->er_extcount) * | 4565 | * xfs_iext_irec_remove. |
4631 | sizeof(xfs_bmbt_rec_t)); | 4566 | */ |
4567 | kmem_free(erp_next->er_extbuf); | ||
4568 | erp_next->er_extbuf = NULL; | ||
4569 | xfs_iext_irec_remove(ifp, erp_idx + 1); | ||
4570 | erp = &ifp->if_u1.if_ext_irec[erp_idx]; | ||
4571 | nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ; | ||
4572 | |||
4573 | /* | ||
4574 | * If the next irec is not empty move up the content | ||
4575 | * that has not been copied to the previous page to | ||
4576 | * the beggining of this one. | ||
4577 | */ | ||
4578 | } else { | ||
4579 | memmove(erp_next->er_extbuf, &ep_next[ext_diff], | ||
4580 | erp_next->er_extcount * | ||
4581 | sizeof(xfs_bmbt_rec_t)); | ||
4582 | ep_next = erp_next->er_extbuf; | ||
4583 | memset(&ep_next[erp_next->er_extcount], 0, | ||
4584 | (XFS_LINEAR_EXTS - | ||
4585 | erp_next->er_extcount) * | ||
4586 | sizeof(xfs_bmbt_rec_t)); | ||
4587 | } | ||
4632 | } | 4588 | } |
4589 | |||
4633 | if (erp->er_extcount == XFS_LINEAR_EXTS) { | 4590 | if (erp->er_extcount == XFS_LINEAR_EXTS) { |
4634 | erp_idx++; | 4591 | erp_idx++; |
4635 | if (erp_idx < nlists) | 4592 | if (erp_idx < nlists) |