]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/xfs/xfs_inode.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
[linux-2.6-omap-h63xx.git] / fs / xfs / xfs_inode.c
index e569bf5d6cf0d9509356e93aef781048202c669b..bedc66163176484b5dc7e7911637ab0059e6c0a8 100644 (file)
@@ -1763,67 +1763,6 @@ xfs_itruncate_finish(
        return 0;
 }
 
-
-/*
- * xfs_igrow_start
- *
- * Do the first part of growing a file: zero any data in the last
- * block that is beyond the old EOF.  We need to do this before
- * the inode is joined to the transaction to modify the i_size.
- * That way we can drop the inode lock and call into the buffer
- * cache to get the buffer mapping the EOF.
- */
-int
-xfs_igrow_start(
-       xfs_inode_t     *ip,
-       xfs_fsize_t     new_size,
-       cred_t          *credp)
-{
-       ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL));
-       ASSERT(new_size > ip->i_size);
-
-       /*
-        * Zero any pages that may have been created by
-        * xfs_write_file() beyond the end of the file
-        * and any blocks between the old and new file sizes.
-        */
-       return xfs_zero_eof(ip, new_size, ip->i_size);
-}
-
-/*
- * xfs_igrow_finish
- *
- * This routine is called to extend the size of a file.
- * The inode must have both the iolock and the ilock locked
- * for update and it must be a part of the current transaction.
- * The xfs_igrow_start() function must have been called previously.
- * If the change_flag is not zero, the inode change timestamp will
- * be updated.
- */
-void
-xfs_igrow_finish(
-       xfs_trans_t     *tp,
-       xfs_inode_t     *ip,
-       xfs_fsize_t     new_size,
-       int             change_flag)
-{
-       ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL));
-       ASSERT(ip->i_transp == tp);
-       ASSERT(new_size > ip->i_size);
-
-       /*
-        * Update the file size.  Update the inode change timestamp
-        * if change_flag set.
-        */
-       ip->i_d.di_size = new_size;
-       ip->i_size = new_size;
-       if (change_flag)
-               xfs_ichgtime(ip, XFS_ICHGTIME_CHG);
-       xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-
-}
-
-
 /*
  * This is called when the inode's link count goes to 0.
  * We place the on-disk inode on a list in the AGI.  It
@@ -2258,7 +2197,7 @@ xfs_ifree_cluster(
                xfs_trans_binval(tp, bp);
        }
 
-       kmem_free(ip_found, ninodes * sizeof(xfs_inode_t *));
+       kmem_free(ip_found);
        xfs_put_perag(mp, pag);
 }
 
@@ -2470,7 +2409,7 @@ xfs_iroot_realloc(
                                                     (int)new_size);
                memcpy(np, op, new_max * (uint)sizeof(xfs_dfsbno_t));
        }
-       kmem_free(ifp->if_broot, ifp->if_broot_bytes);
+       kmem_free(ifp->if_broot);
        ifp->if_broot = new_broot;
        ifp->if_broot_bytes = (int)new_size;
        ASSERT(ifp->if_broot_bytes <=
@@ -2514,7 +2453,7 @@ xfs_idata_realloc(
 
        if (new_size == 0) {
                if (ifp->if_u1.if_data != ifp->if_u2.if_inline_data) {
-                       kmem_free(ifp->if_u1.if_data, ifp->if_real_bytes);
+                       kmem_free(ifp->if_u1.if_data);
                }
                ifp->if_u1.if_data = NULL;
                real_size = 0;
@@ -2529,7 +2468,7 @@ xfs_idata_realloc(
                        ASSERT(ifp->if_real_bytes != 0);
                        memcpy(ifp->if_u2.if_inline_data, ifp->if_u1.if_data,
                              new_size);
-                       kmem_free(ifp->if_u1.if_data, ifp->if_real_bytes);
+                       kmem_free(ifp->if_u1.if_data);
                        ifp->if_u1.if_data = ifp->if_u2.if_inline_data;
                }
                real_size = 0;
@@ -2636,7 +2575,7 @@ xfs_idestroy_fork(
 
        ifp = XFS_IFORK_PTR(ip, whichfork);
        if (ifp->if_broot != NULL) {
-               kmem_free(ifp->if_broot, ifp->if_broot_bytes);
+               kmem_free(ifp->if_broot);
                ifp->if_broot = NULL;
        }
 
@@ -2650,7 +2589,7 @@ xfs_idestroy_fork(
                if ((ifp->if_u1.if_data != ifp->if_u2.if_inline_data) &&
                    (ifp->if_u1.if_data != NULL)) {
                        ASSERT(ifp->if_real_bytes != 0);
-                       kmem_free(ifp->if_u1.if_data, ifp->if_real_bytes);
+                       kmem_free(ifp->if_u1.if_data);
                        ifp->if_u1.if_data = NULL;
                        ifp->if_real_bytes = 0;
                }
@@ -3058,7 +2997,7 @@ xfs_iflush_cluster(
 
 out_free:
        read_unlock(&pag->pag_ici_lock);
-       kmem_free(ilist, ilist_size);
+       kmem_free(ilist);
        return 0;
 
 
@@ -3102,7 +3041,7 @@ cluster_corrupt_out:
         * Unlocks the flush lock
         */
        xfs_iflush_abort(iq);
-       kmem_free(ilist, ilist_size);
+       kmem_free(ilist);
        return XFS_ERROR(EFSCORRUPTED);
 }
 
@@ -3143,8 +3082,6 @@ xfs_iflush(
         * flush lock and do nothing.
         */
        if (xfs_inode_clean(ip)) {
-               ASSERT((iip != NULL) ?
-                        !(iip->ili_item.li_flags & XFS_LI_IN_AIL) : 1);
                xfs_ifunlock(ip);
                return 0;
        }
@@ -3836,7 +3773,7 @@ xfs_iext_add_indirect_multi(
                        erp = xfs_iext_irec_new(ifp, erp_idx);
                }
                memmove(&erp->er_extbuf[i], nex2_ep, byte_diff);
-               kmem_free(nex2_ep, byte_diff);
+               kmem_free(nex2_ep);
                erp->er_extcount += nex2;
                xfs_iext_irec_update_extoffs(ifp, erp_idx + 1, nex2);
        }
@@ -4112,7 +4049,7 @@ xfs_iext_direct_to_inline(
         */
        memcpy(ifp->if_u2.if_inline_ext, ifp->if_u1.if_extents,
                nextents * sizeof(xfs_bmbt_rec_t));
-       kmem_free(ifp->if_u1.if_extents, ifp->if_real_bytes);
+       kmem_free(ifp->if_u1.if_extents);
        ifp->if_u1.if_extents = ifp->if_u2.if_inline_ext;
        ifp->if_real_bytes = 0;
 }
@@ -4186,7 +4123,7 @@ xfs_iext_indirect_to_direct(
        ASSERT(ifp->if_real_bytes == XFS_IEXT_BUFSZ);
 
        ep = ifp->if_u1.if_ext_irec->er_extbuf;
-       kmem_free(ifp->if_u1.if_ext_irec, sizeof(xfs_ext_irec_t));
+       kmem_free(ifp->if_u1.if_ext_irec);
        ifp->if_flags &= ~XFS_IFEXTIREC;
        ifp->if_u1.if_extents = ep;
        ifp->if_bytes = size;
@@ -4212,7 +4149,7 @@ xfs_iext_destroy(
                }
                ifp->if_flags &= ~XFS_IFEXTIREC;
        } else if (ifp->if_real_bytes) {
-               kmem_free(ifp->if_u1.if_extents, ifp->if_real_bytes);
+               kmem_free(ifp->if_u1.if_extents);
        } else if (ifp->if_bytes) {
                memset(ifp->if_u2.if_inline_ext, 0, XFS_INLINE_EXTS *
                        sizeof(xfs_bmbt_rec_t));
@@ -4483,7 +4420,7 @@ xfs_iext_irec_remove(
        if (erp->er_extbuf) {
                xfs_iext_irec_update_extoffs(ifp, erp_idx + 1,
                        -erp->er_extcount);
-               kmem_free(erp->er_extbuf, XFS_IEXT_BUFSZ);
+               kmem_free(erp->er_extbuf);
        }
        /* Compact extent records */
        erp = ifp->if_u1.if_ext_irec;
@@ -4501,8 +4438,7 @@ xfs_iext_irec_remove(
                xfs_iext_realloc_indirect(ifp,
                        nlists * sizeof(xfs_ext_irec_t));
        } else {
-               kmem_free(ifp->if_u1.if_ext_irec,
-                       sizeof(xfs_ext_irec_t));
+               kmem_free(ifp->if_u1.if_ext_irec);
        }
        ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ;
 }
@@ -4571,7 +4507,7 @@ xfs_iext_irec_compact_pages(
                         * so er_extoffs don't get modified in
                         * xfs_iext_irec_remove.
                         */
-                       kmem_free(erp_next->er_extbuf, XFS_IEXT_BUFSZ);
+                       kmem_free(erp_next->er_extbuf);
                        erp_next->er_extbuf = NULL;
                        xfs_iext_irec_remove(ifp, erp_idx + 1);
                        nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
@@ -4596,40 +4532,63 @@ xfs_iext_irec_compact_full(
        int             nlists;                 /* number of irec's (ex lists) */
 
        ASSERT(ifp->if_flags & XFS_IFEXTIREC);
+
        nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
        erp = ifp->if_u1.if_ext_irec;
        ep = &erp->er_extbuf[erp->er_extcount];
        erp_next = erp + 1;
        ep_next = erp_next->er_extbuf;
+
        while (erp_idx < nlists - 1) {
+               /*
+                * Check how many extent records are available in this irec.
+                * If there is none skip the whole exercise.
+                */
                ext_avail = XFS_LINEAR_EXTS - erp->er_extcount;
-               ext_diff = MIN(ext_avail, erp_next->er_extcount);
-               memcpy(ep, ep_next, ext_diff * sizeof(xfs_bmbt_rec_t));
-               erp->er_extcount += ext_diff;
-               erp_next->er_extcount -= ext_diff;
-               /* Remove next page */
-               if (erp_next->er_extcount == 0) {
+               if (ext_avail) {
+
                        /*
-                        * Free page before removing extent record
-                        * so er_extoffs don't get modified in
-                        * xfs_iext_irec_remove.
+                        * Copy over as many as possible extent records into
+                        * the previous page.
                         */
-                       kmem_free(erp_next->er_extbuf,
-                               erp_next->er_extcount * sizeof(xfs_bmbt_rec_t));
-                       erp_next->er_extbuf = NULL;
-                       xfs_iext_irec_remove(ifp, erp_idx + 1);
-                       erp = &ifp->if_u1.if_ext_irec[erp_idx];
-                       nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
-               /* Update next page */
-               } else {
-                       /* Move rest of page up to become next new page */
-                       memmove(erp_next->er_extbuf, ep_next,
-                               erp_next->er_extcount * sizeof(xfs_bmbt_rec_t));
-                       ep_next = erp_next->er_extbuf;
-                       memset(&ep_next[erp_next->er_extcount], 0,
-                               (XFS_LINEAR_EXTS - erp_next->er_extcount) *
-                               sizeof(xfs_bmbt_rec_t));
+                       ext_diff = MIN(ext_avail, erp_next->er_extcount);
+                       memcpy(ep, ep_next, ext_diff * sizeof(xfs_bmbt_rec_t));
+                       erp->er_extcount += ext_diff;
+                       erp_next->er_extcount -= ext_diff;
+
+                       /*
+                        * If the next irec is empty now we can simply
+                        * remove it.
+                        */
+                       if (erp_next->er_extcount == 0) {
+                               /*
+                                * Free page before removing extent record
+                                * so er_extoffs don't get modified in
+                                * xfs_iext_irec_remove.
+                                */
+                               kmem_free(erp_next->er_extbuf);
+                               erp_next->er_extbuf = NULL;
+                               xfs_iext_irec_remove(ifp, erp_idx + 1);
+                               erp = &ifp->if_u1.if_ext_irec[erp_idx];
+                               nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
+
+                       /*
+                        * If the next irec is not empty move up the content
+                        * that has not been copied to the previous page to
+                        * the beggining of this one.
+                        */
+                       } else {
+                               memmove(erp_next->er_extbuf, &ep_next[ext_diff],
+                                       erp_next->er_extcount *
+                                       sizeof(xfs_bmbt_rec_t));
+                               ep_next = erp_next->er_extbuf;
+                               memset(&ep_next[erp_next->er_extcount], 0,
+                                       (XFS_LINEAR_EXTS -
+                                               erp_next->er_extcount) *
+                                       sizeof(xfs_bmbt_rec_t));
+                       }
                }
+
                if (erp->er_extcount == XFS_LINEAR_EXTS) {
                        erp_idx++;
                        if (erp_idx < nlists)