xfs: I/O completion handlers must use NOFS allocations
[safe/jmp/linux-2.6] / fs / xfs / xfs_inode_item.c
index 291d30a..9794b87 100644 (file)
@@ -232,6 +232,15 @@ xfs_inode_item_format(
        nvecs        = 1;
 
        /*
+        * Make sure the linux inode is dirty. We do this before
+        * clearing i_update_core as the VFS will call back into
+        * XFS here and set i_update_core, so we need to dirty the
+        * inode first so that the ordering of i_update_core and
+        * unlogged modifications still works as described below.
+        */
+       xfs_mark_inode_dirty_sync(ip);
+
+       /*
         * Clear i_update_core if the timestamps (or any other
         * non-transactional modification) need flushing/logging
         * and we're about to log them with the rest of the core.
@@ -263,25 +272,12 @@ xfs_inode_item_format(
        }
 
        /*
-        * We don't have to worry about re-ordering here because
-        * the update_size field is protected by the inode lock
-        * and we have that held in exclusive mode.
-        */
-       if (ip->i_update_size)
-               ip->i_update_size = 0;
-
-       /*
-        * Make sure to get the latest atime from the Linux inode.
+        * Make sure to get the latest timestamps from the Linux inode.
         */
-       xfs_synchronize_atime(ip);
-
-       /*
-        * make sure the linux inode is dirty
-        */
-       xfs_mark_inode_dirty_sync(ip);
+       xfs_synchronize_times(ip);
 
        vecp->i_addr = (xfs_caddr_t)&ip->i_d;
-       vecp->i_len  = sizeof(xfs_dinode_core_t);
+       vecp->i_len  = sizeof(struct xfs_icdinode);
        XLOG_VEC_SET_TYPE(vecp, XLOG_REG_TYPE_ICORE);
        vecp++;
        nvecs++;
@@ -296,9 +292,8 @@ xfs_inode_item_format(
         * has a new version number, then we don't bother converting back.
         */
        mp = ip->i_mount;
-       ASSERT(ip->i_d.di_version == XFS_DINODE_VERSION_1 ||
-              xfs_sb_version_hasnlink(&mp->m_sb));
-       if (ip->i_d.di_version == XFS_DINODE_VERSION_1) {
+       ASSERT(ip->i_d.di_version == 1 || xfs_sb_version_hasnlink(&mp->m_sb));
+       if (ip->i_d.di_version == 1) {
                if (!xfs_sb_version_hasnlink(&mp->m_sb)) {
                        /*
                         * Convert it back.
@@ -311,7 +306,7 @@ xfs_inode_item_format(
                         * so just make the conversion to the new inode
                         * format permanent.
                         */
-                       ip->i_d.di_version = XFS_DINODE_VERSION_2;
+                       ip->i_d.di_version = 2;
                        ip->i_d.di_onlink = 0;
                        memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
                }
@@ -713,8 +708,6 @@ xfs_inode_item_unlock(
         * Clear out the fields of the inode log item particular
         * to the current transaction.
         */
-       iip->ili_ilock_recur = 0;
-       iip->ili_iolock_recur = 0;
        iip->ili_flags = 0;
 
        /*
@@ -932,6 +925,7 @@ xfs_inode_item_init(
        iip->ili_item.li_type = XFS_LI_INODE;
        iip->ili_item.li_ops = &xfs_inode_item_ops;
        iip->ili_item.li_mountp = mp;
+       iip->ili_item.li_ailp = mp->m_ail;
        iip->ili_inode = ip;
 
        /*
@@ -942,9 +936,9 @@ xfs_inode_item_init(
 
        iip->ili_format.ilf_type = XFS_LI_INODE;
        iip->ili_format.ilf_ino = ip->i_ino;
-       iip->ili_format.ilf_blkno = ip->i_blkno;
-       iip->ili_format.ilf_len = ip->i_len;
-       iip->ili_format.ilf_boffset = ip->i_boffset;
+       iip->ili_format.ilf_blkno = ip->i_imap.im_blkno;
+       iip->ili_format.ilf_len = ip->i_imap.im_len;
+       iip->ili_format.ilf_boffset = ip->i_imap.im_boffset;
 }
 
 /*
@@ -976,9 +970,8 @@ xfs_iflush_done(
        xfs_buf_t               *bp,
        xfs_inode_log_item_t    *iip)
 {
-       xfs_inode_t     *ip;
-
-       ip = iip->ili_inode;
+       xfs_inode_t             *ip = iip->ili_inode;
+       struct xfs_ail          *ailp = iip->ili_item.li_ailp;
 
        /*
         * We only want to pull the item from the AIL if it is
@@ -991,15 +984,12 @@ xfs_iflush_done(
         */
        if (iip->ili_logged &&
            (iip->ili_item.li_lsn == iip->ili_flush_lsn)) {
-               spin_lock(&ip->i_mount->m_ail->xa_lock);
+               spin_lock(&ailp->xa_lock);
                if (iip->ili_item.li_lsn == iip->ili_flush_lsn) {
-                       /*
-                        * xfs_trans_delete_ail() drops the AIL lock.
-                        */
-                       xfs_trans_delete_ail(ip->i_mount,
-                                            (xfs_log_item_t*)iip);
+                       /* xfs_trans_ail_delete() drops the AIL lock. */
+                       xfs_trans_ail_delete(ailp, (xfs_log_item_t*)iip);
                } else {
-                       spin_unlock(&ip->i_mount->m_ail->xa_lock);
+                       spin_unlock(&ailp->xa_lock);
                }
        }
 
@@ -1031,21 +1021,20 @@ void
 xfs_iflush_abort(
        xfs_inode_t             *ip)
 {
-       xfs_inode_log_item_t    *iip;
+       xfs_inode_log_item_t    *iip = ip->i_itemp;
        xfs_mount_t             *mp;
 
        iip = ip->i_itemp;
        mp = ip->i_mount;
        if (iip) {
+               struct xfs_ail  *ailp = iip->ili_item.li_ailp;
                if (iip->ili_item.li_flags & XFS_LI_IN_AIL) {
-                       spin_lock(&mp->m_ail->xa_lock);
+                       spin_lock(&ailp->xa_lock);
                        if (iip->ili_item.li_flags & XFS_LI_IN_AIL) {
-                               /*
-                                * xfs_trans_delete_ail() drops the AIL lock.
-                                */
-                               xfs_trans_delete_ail(mp, (xfs_log_item_t *)iip);
+                               /* xfs_trans_ail_delete() drops the AIL lock. */
+                               xfs_trans_ail_delete(ailp, (xfs_log_item_t *)iip);
                        } else
-                               spin_unlock(&mp->m_ail->xa_lock);
+                               spin_unlock(&ailp->xa_lock);
                }
                iip->ili_logged = 0;
                /*