diff options
author | Christoph Hellwig <hch@infradead.org> | 2012-02-29 04:53:54 -0500 |
---|---|---|
committer | Ben Myers <bpm@sgi.com> | 2012-03-13 18:08:17 -0400 |
commit | f5d8d5c4bf29c9f7754d9cbe5e27c785106ba872 (patch) | |
tree | edb30eef42b3a26e5e9c33448e85a812971cbc30 /fs/xfs/xfs_inode.c | |
parent | 339a5f5dd9d3ac3d68a594d81507e1eab77ed223 (diff) |
xfs: split in-core and on-disk inode log item fields
Add a new ili_fields member to the inode log item to isolate the in-memory
flags from the ones that actually go to the log. This will allow tracking
timestamp-only updates for fdatasync and O_DSYNC in the next patch and
prepares for divorcing the on-disk log format from the in-memory log item
a little further down the road.
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r-- | fs/xfs/xfs_inode.c | 69 |
1 files changed, 33 insertions, 36 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 7ce9ccbf17c4..bc46c0a133d3 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -1661,8 +1661,8 @@ retry: | |||
1661 | continue; | 1661 | continue; |
1662 | } | 1662 | } |
1663 | 1663 | ||
1664 | iip->ili_last_fields = iip->ili_format.ilf_fields; | 1664 | iip->ili_last_fields = iip->ili_fields; |
1665 | iip->ili_format.ilf_fields = 0; | 1665 | iip->ili_fields = 0; |
1666 | iip->ili_logged = 1; | 1666 | iip->ili_logged = 1; |
1667 | xfs_trans_ail_copy_lsn(mp->m_ail, &iip->ili_flush_lsn, | 1667 | xfs_trans_ail_copy_lsn(mp->m_ail, &iip->ili_flush_lsn, |
1668 | &iip->ili_item.li_lsn); | 1668 | &iip->ili_item.li_lsn); |
@@ -2176,7 +2176,7 @@ xfs_iflush_fork( | |||
2176 | mp = ip->i_mount; | 2176 | mp = ip->i_mount; |
2177 | switch (XFS_IFORK_FORMAT(ip, whichfork)) { | 2177 | switch (XFS_IFORK_FORMAT(ip, whichfork)) { |
2178 | case XFS_DINODE_FMT_LOCAL: | 2178 | case XFS_DINODE_FMT_LOCAL: |
2179 | if ((iip->ili_format.ilf_fields & dataflag[whichfork]) && | 2179 | if ((iip->ili_fields & dataflag[whichfork]) && |
2180 | (ifp->if_bytes > 0)) { | 2180 | (ifp->if_bytes > 0)) { |
2181 | ASSERT(ifp->if_u1.if_data != NULL); | 2181 | ASSERT(ifp->if_u1.if_data != NULL); |
2182 | ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork)); | 2182 | ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork)); |
@@ -2186,8 +2186,8 @@ xfs_iflush_fork( | |||
2186 | 2186 | ||
2187 | case XFS_DINODE_FMT_EXTENTS: | 2187 | case XFS_DINODE_FMT_EXTENTS: |
2188 | ASSERT((ifp->if_flags & XFS_IFEXTENTS) || | 2188 | ASSERT((ifp->if_flags & XFS_IFEXTENTS) || |
2189 | !(iip->ili_format.ilf_fields & extflag[whichfork])); | 2189 | !(iip->ili_fields & extflag[whichfork])); |
2190 | if ((iip->ili_format.ilf_fields & extflag[whichfork]) && | 2190 | if ((iip->ili_fields & extflag[whichfork]) && |
2191 | (ifp->if_bytes > 0)) { | 2191 | (ifp->if_bytes > 0)) { |
2192 | ASSERT(xfs_iext_get_ext(ifp, 0)); | 2192 | ASSERT(xfs_iext_get_ext(ifp, 0)); |
2193 | ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) > 0); | 2193 | ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) > 0); |
@@ -2197,7 +2197,7 @@ xfs_iflush_fork( | |||
2197 | break; | 2197 | break; |
2198 | 2198 | ||
2199 | case XFS_DINODE_FMT_BTREE: | 2199 | case XFS_DINODE_FMT_BTREE: |
2200 | if ((iip->ili_format.ilf_fields & brootflag[whichfork]) && | 2200 | if ((iip->ili_fields & brootflag[whichfork]) && |
2201 | (ifp->if_broot_bytes > 0)) { | 2201 | (ifp->if_broot_bytes > 0)) { |
2202 | ASSERT(ifp->if_broot != NULL); | 2202 | ASSERT(ifp->if_broot != NULL); |
2203 | ASSERT(ifp->if_broot_bytes <= | 2203 | ASSERT(ifp->if_broot_bytes <= |
@@ -2210,14 +2210,14 @@ xfs_iflush_fork( | |||
2210 | break; | 2210 | break; |
2211 | 2211 | ||
2212 | case XFS_DINODE_FMT_DEV: | 2212 | case XFS_DINODE_FMT_DEV: |
2213 | if (iip->ili_format.ilf_fields & XFS_ILOG_DEV) { | 2213 | if (iip->ili_fields & XFS_ILOG_DEV) { |
2214 | ASSERT(whichfork == XFS_DATA_FORK); | 2214 | ASSERT(whichfork == XFS_DATA_FORK); |
2215 | xfs_dinode_put_rdev(dip, ip->i_df.if_u2.if_rdev); | 2215 | xfs_dinode_put_rdev(dip, ip->i_df.if_u2.if_rdev); |
2216 | } | 2216 | } |
2217 | break; | 2217 | break; |
2218 | 2218 | ||
2219 | case XFS_DINODE_FMT_UUID: | 2219 | case XFS_DINODE_FMT_UUID: |
2220 | if (iip->ili_format.ilf_fields & XFS_ILOG_UUID) { | 2220 | if (iip->ili_fields & XFS_ILOG_UUID) { |
2221 | ASSERT(whichfork == XFS_DATA_FORK); | 2221 | ASSERT(whichfork == XFS_DATA_FORK); |
2222 | memcpy(XFS_DFORK_DPTR(dip), | 2222 | memcpy(XFS_DFORK_DPTR(dip), |
2223 | &ip->i_df.if_u2.if_uuid, | 2223 | &ip->i_df.if_u2.if_uuid, |
@@ -2451,7 +2451,7 @@ xfs_iflush( | |||
2451 | */ | 2451 | */ |
2452 | if (XFS_FORCED_SHUTDOWN(mp)) { | 2452 | if (XFS_FORCED_SHUTDOWN(mp)) { |
2453 | if (iip) | 2453 | if (iip) |
2454 | iip->ili_format.ilf_fields = 0; | 2454 | iip->ili_fields = 0; |
2455 | xfs_ifunlock(ip); | 2455 | xfs_ifunlock(ip); |
2456 | return XFS_ERROR(EIO); | 2456 | return XFS_ERROR(EIO); |
2457 | } | 2457 | } |
@@ -2641,36 +2641,33 @@ xfs_iflush_int( | |||
2641 | xfs_inobp_check(mp, bp); | 2641 | xfs_inobp_check(mp, bp); |
2642 | 2642 | ||
2643 | /* | 2643 | /* |
2644 | * We've recorded everything logged in the inode, so we'd | 2644 | * We've recorded everything logged in the inode, so we'd like to clear |
2645 | * like to clear the ilf_fields bits so we don't log and | 2645 | * the ili_fields bits so we don't log and flush things unnecessarily. |
2646 | * flush things unnecessarily. However, we can't stop | 2646 | * However, we can't stop logging all this information until the data |
2647 | * logging all this information until the data we've copied | 2647 | * we've copied into the disk buffer is written to disk. If we did we |
2648 | * into the disk buffer is written to disk. If we did we might | 2648 | * might overwrite the copy of the inode in the log with all the data |
2649 | * overwrite the copy of the inode in the log with all the | 2649 | * after re-logging only part of it, and in the face of a crash we |
2650 | * data after re-logging only part of it, and in the face of | 2650 | * wouldn't have all the data we need to recover. |
2651 | * a crash we wouldn't have all the data we need to recover. | ||
2652 | * | 2651 | * |
2653 | * What we do is move the bits to the ili_last_fields field. | 2652 | * What we do is move the bits to the ili_last_fields field. When |
2654 | * When logging the inode, these bits are moved back to the | 2653 | * logging the inode, these bits are moved back to the ili_fields field. |
2655 | * ilf_fields field. In the xfs_iflush_done() routine we | 2654 | * In the xfs_iflush_done() routine we clear ili_last_fields, since we |
2656 | * clear ili_last_fields, since we know that the information | 2655 | * know that the information those bits represent is permanently on |
2657 | * those bits represent is permanently on disk. As long as | 2656 | * disk. As long as the flush completes before the inode is logged |
2658 | * the flush completes before the inode is logged again, then | 2657 | * again, then both ili_fields and ili_last_fields will be cleared. |
2659 | * both ilf_fields and ili_last_fields will be cleared. | ||
2660 | * | 2658 | * |
2661 | * We can play with the ilf_fields bits here, because the inode | 2659 | * We can play with the ili_fields bits here, because the inode lock |
2662 | * lock must be held exclusively in order to set bits there | 2660 | * must be held exclusively in order to set bits there and the flush |
2663 | * and the flush lock protects the ili_last_fields bits. | 2661 | * lock protects the ili_last_fields bits. Set ili_logged so the flush |
2664 | * Set ili_logged so the flush done | 2662 | * done routine can tell whether or not to look in the AIL. Also, store |
2665 | * routine can tell whether or not to look in the AIL. | 2663 | * the current LSN of the inode so that we can tell whether the item has |
2666 | * Also, store the current LSN of the inode so that we can tell | 2664 | * moved in the AIL from xfs_iflush_done(). In order to read the lsn we |
2667 | * whether the item has moved in the AIL from xfs_iflush_done(). | 2665 | * need the AIL lock, because it is a 64 bit value that cannot be read |
2668 | * In order to read the lsn we need the AIL lock, because | 2666 | * atomically. |
2669 | * it is a 64 bit value that cannot be read atomically. | ||
2670 | */ | 2667 | */ |
2671 | if (iip != NULL && iip->ili_format.ilf_fields != 0) { | 2668 | if (iip != NULL && iip->ili_fields != 0) { |
2672 | iip->ili_last_fields = iip->ili_format.ilf_fields; | 2669 | iip->ili_last_fields = iip->ili_fields; |
2673 | iip->ili_format.ilf_fields = 0; | 2670 | iip->ili_fields = 0; |
2674 | iip->ili_logged = 1; | 2671 | iip->ili_logged = 1; |
2675 | 2672 | ||
2676 | xfs_trans_ail_copy_lsn(mp->m_ail, &iip->ili_flush_lsn, | 2673 | xfs_trans_ail_copy_lsn(mp->m_ail, &iip->ili_flush_lsn, |