aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r--fs/xfs/xfs_inode.c235
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 */
1776int
1777xfs_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 */
1803void
1804xfs_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
3059out_free: 3000out_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 */
3118int 3059int
@@ -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)