提交 f5d8d5c4 编写于 作者: C Christoph Hellwig 提交者: Ben Myers

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: NDave Chinner <dchinner@redhat.com>
Signed-off-by: NChristoph Hellwig <hch@lst.de>
Reviewed-by: NMark Tinguely <tinguely@sgi.com>
Signed-off-by: NBen Myers <bpm@sgi.com>
上级 339a5f5d
...@@ -215,7 +215,7 @@ xfs_swap_extents( ...@@ -215,7 +215,7 @@ xfs_swap_extents(
xfs_trans_t *tp; xfs_trans_t *tp;
xfs_bstat_t *sbp = &sxp->sx_stat; xfs_bstat_t *sbp = &sxp->sx_stat;
xfs_ifork_t *tempifp, *ifp, *tifp; xfs_ifork_t *tempifp, *ifp, *tifp;
int ilf_fields, tilf_fields; int src_log_flags, target_log_flags;
int error = 0; int error = 0;
int aforkblks = 0; int aforkblks = 0;
int taforkblks = 0; int taforkblks = 0;
...@@ -385,9 +385,8 @@ xfs_swap_extents( ...@@ -385,9 +385,8 @@ xfs_swap_extents(
tip->i_delayed_blks = ip->i_delayed_blks; tip->i_delayed_blks = ip->i_delayed_blks;
ip->i_delayed_blks = 0; ip->i_delayed_blks = 0;
ilf_fields = XFS_ILOG_CORE; src_log_flags = XFS_ILOG_CORE;
switch (ip->i_d.di_format) {
switch(ip->i_d.di_format) {
case XFS_DINODE_FMT_EXTENTS: case XFS_DINODE_FMT_EXTENTS:
/* If the extents fit in the inode, fix the /* If the extents fit in the inode, fix the
* pointer. Otherwise it's already NULL or * pointer. Otherwise it's already NULL or
...@@ -397,16 +396,15 @@ xfs_swap_extents( ...@@ -397,16 +396,15 @@ xfs_swap_extents(
ifp->if_u1.if_extents = ifp->if_u1.if_extents =
ifp->if_u2.if_inline_ext; ifp->if_u2.if_inline_ext;
} }
ilf_fields |= XFS_ILOG_DEXT; src_log_flags |= XFS_ILOG_DEXT;
break; break;
case XFS_DINODE_FMT_BTREE: case XFS_DINODE_FMT_BTREE:
ilf_fields |= XFS_ILOG_DBROOT; src_log_flags |= XFS_ILOG_DBROOT;
break; break;
} }
tilf_fields = XFS_ILOG_CORE; target_log_flags = XFS_ILOG_CORE;
switch (tip->i_d.di_format) {
switch(tip->i_d.di_format) {
case XFS_DINODE_FMT_EXTENTS: case XFS_DINODE_FMT_EXTENTS:
/* If the extents fit in the inode, fix the /* If the extents fit in the inode, fix the
* pointer. Otherwise it's already NULL or * pointer. Otherwise it's already NULL or
...@@ -416,10 +414,10 @@ xfs_swap_extents( ...@@ -416,10 +414,10 @@ xfs_swap_extents(
tifp->if_u1.if_extents = tifp->if_u1.if_extents =
tifp->if_u2.if_inline_ext; tifp->if_u2.if_inline_ext;
} }
tilf_fields |= XFS_ILOG_DEXT; target_log_flags |= XFS_ILOG_DEXT;
break; break;
case XFS_DINODE_FMT_BTREE: case XFS_DINODE_FMT_BTREE:
tilf_fields |= XFS_ILOG_DBROOT; target_log_flags |= XFS_ILOG_DBROOT;
break; break;
} }
...@@ -427,8 +425,8 @@ xfs_swap_extents( ...@@ -427,8 +425,8 @@ xfs_swap_extents(
xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
xfs_trans_ijoin(tp, tip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); xfs_trans_ijoin(tp, tip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
xfs_trans_log_inode(tp, ip, ilf_fields); xfs_trans_log_inode(tp, ip, src_log_flags);
xfs_trans_log_inode(tp, tip, tilf_fields); xfs_trans_log_inode(tp, tip, target_log_flags);
/* /*
* If this is a synchronous mount, make sure that the * If this is a synchronous mount, make sure that the
......
...@@ -1661,8 +1661,8 @@ xfs_ifree_cluster( ...@@ -1661,8 +1661,8 @@ xfs_ifree_cluster(
continue; continue;
} }
iip->ili_last_fields = iip->ili_format.ilf_fields; iip->ili_last_fields = iip->ili_fields;
iip->ili_format.ilf_fields = 0; iip->ili_fields = 0;
iip->ili_logged = 1; iip->ili_logged = 1;
xfs_trans_ail_copy_lsn(mp->m_ail, &iip->ili_flush_lsn, xfs_trans_ail_copy_lsn(mp->m_ail, &iip->ili_flush_lsn,
&iip->ili_item.li_lsn); &iip->ili_item.li_lsn);
...@@ -2176,7 +2176,7 @@ xfs_iflush_fork( ...@@ -2176,7 +2176,7 @@ xfs_iflush_fork(
mp = ip->i_mount; mp = ip->i_mount;
switch (XFS_IFORK_FORMAT(ip, whichfork)) { switch (XFS_IFORK_FORMAT(ip, whichfork)) {
case XFS_DINODE_FMT_LOCAL: case XFS_DINODE_FMT_LOCAL:
if ((iip->ili_format.ilf_fields & dataflag[whichfork]) && if ((iip->ili_fields & dataflag[whichfork]) &&
(ifp->if_bytes > 0)) { (ifp->if_bytes > 0)) {
ASSERT(ifp->if_u1.if_data != NULL); ASSERT(ifp->if_u1.if_data != NULL);
ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork)); ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork));
...@@ -2186,8 +2186,8 @@ xfs_iflush_fork( ...@@ -2186,8 +2186,8 @@ xfs_iflush_fork(
case XFS_DINODE_FMT_EXTENTS: case XFS_DINODE_FMT_EXTENTS:
ASSERT((ifp->if_flags & XFS_IFEXTENTS) || ASSERT((ifp->if_flags & XFS_IFEXTENTS) ||
!(iip->ili_format.ilf_fields & extflag[whichfork])); !(iip->ili_fields & extflag[whichfork]));
if ((iip->ili_format.ilf_fields & extflag[whichfork]) && if ((iip->ili_fields & extflag[whichfork]) &&
(ifp->if_bytes > 0)) { (ifp->if_bytes > 0)) {
ASSERT(xfs_iext_get_ext(ifp, 0)); ASSERT(xfs_iext_get_ext(ifp, 0));
ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) > 0); ASSERT(XFS_IFORK_NEXTENTS(ip, whichfork) > 0);
...@@ -2197,7 +2197,7 @@ xfs_iflush_fork( ...@@ -2197,7 +2197,7 @@ xfs_iflush_fork(
break; break;
case XFS_DINODE_FMT_BTREE: case XFS_DINODE_FMT_BTREE:
if ((iip->ili_format.ilf_fields & brootflag[whichfork]) && if ((iip->ili_fields & brootflag[whichfork]) &&
(ifp->if_broot_bytes > 0)) { (ifp->if_broot_bytes > 0)) {
ASSERT(ifp->if_broot != NULL); ASSERT(ifp->if_broot != NULL);
ASSERT(ifp->if_broot_bytes <= ASSERT(ifp->if_broot_bytes <=
...@@ -2210,14 +2210,14 @@ xfs_iflush_fork( ...@@ -2210,14 +2210,14 @@ xfs_iflush_fork(
break; break;
case XFS_DINODE_FMT_DEV: case XFS_DINODE_FMT_DEV:
if (iip->ili_format.ilf_fields & XFS_ILOG_DEV) { if (iip->ili_fields & XFS_ILOG_DEV) {
ASSERT(whichfork == XFS_DATA_FORK); ASSERT(whichfork == XFS_DATA_FORK);
xfs_dinode_put_rdev(dip, ip->i_df.if_u2.if_rdev); xfs_dinode_put_rdev(dip, ip->i_df.if_u2.if_rdev);
} }
break; break;
case XFS_DINODE_FMT_UUID: case XFS_DINODE_FMT_UUID:
if (iip->ili_format.ilf_fields & XFS_ILOG_UUID) { if (iip->ili_fields & XFS_ILOG_UUID) {
ASSERT(whichfork == XFS_DATA_FORK); ASSERT(whichfork == XFS_DATA_FORK);
memcpy(XFS_DFORK_DPTR(dip), memcpy(XFS_DFORK_DPTR(dip),
&ip->i_df.if_u2.if_uuid, &ip->i_df.if_u2.if_uuid,
...@@ -2451,7 +2451,7 @@ xfs_iflush( ...@@ -2451,7 +2451,7 @@ xfs_iflush(
*/ */
if (XFS_FORCED_SHUTDOWN(mp)) { if (XFS_FORCED_SHUTDOWN(mp)) {
if (iip) if (iip)
iip->ili_format.ilf_fields = 0; iip->ili_fields = 0;
xfs_ifunlock(ip); xfs_ifunlock(ip);
return XFS_ERROR(EIO); return XFS_ERROR(EIO);
} }
...@@ -2641,36 +2641,33 @@ xfs_iflush_int( ...@@ -2641,36 +2641,33 @@ xfs_iflush_int(
xfs_inobp_check(mp, bp); xfs_inobp_check(mp, bp);
/* /*
* We've recorded everything logged in the inode, so we'd * We've recorded everything logged in the inode, so we'd like to clear
* like to clear the ilf_fields bits so we don't log and * the ili_fields bits so we don't log and flush things unnecessarily.
* flush things unnecessarily. However, we can't stop * However, we can't stop logging all this information until the data
* logging all this information until the data we've copied * we've copied into the disk buffer is written to disk. If we did we
* into the disk buffer is written to disk. If we did we might * might overwrite the copy of the inode in the log with all the data
* overwrite the copy of the inode in the log with all the * after re-logging only part of it, and in the face of a crash we
* data after re-logging only part of it, and in the face of * wouldn't have all the data we need to recover.
* a crash we wouldn't have all the data we need to recover.
* *
* What we do is move the bits to the ili_last_fields field. * What we do is move the bits to the ili_last_fields field. When
* When logging the inode, these bits are moved back to the * logging the inode, these bits are moved back to the ili_fields field.
* ilf_fields field. In the xfs_iflush_done() routine we * In the xfs_iflush_done() routine we clear ili_last_fields, since we
* clear ili_last_fields, since we know that the information * know that the information those bits represent is permanently on
* those bits represent is permanently on disk. As long as * disk. As long as the flush completes before the inode is logged
* the flush completes before the inode is logged again, then * again, then both ili_fields and ili_last_fields will be cleared.
* both ilf_fields and ili_last_fields will be cleared.
* *
* We can play with the ilf_fields bits here, because the inode * We can play with the ili_fields bits here, because the inode lock
* lock must be held exclusively in order to set bits there * must be held exclusively in order to set bits there and the flush
* and the flush lock protects the ili_last_fields bits. * lock protects the ili_last_fields bits. Set ili_logged so the flush
* Set ili_logged so the flush done * done routine can tell whether or not to look in the AIL. Also, store
* routine can tell whether or not to look in the AIL. * the current LSN of the inode so that we can tell whether the item has
* Also, store the current LSN of the inode so that we can tell * moved in the AIL from xfs_iflush_done(). In order to read the lsn we
* whether the item has moved in the AIL from xfs_iflush_done(). * need the AIL lock, because it is a 64 bit value that cannot be read
* In order to read the lsn we need the AIL lock, because * atomically.
* it is a 64 bit value that cannot be read atomically.
*/ */
if (iip != NULL && iip->ili_format.ilf_fields != 0) { if (iip != NULL && iip->ili_fields != 0) {
iip->ili_last_fields = iip->ili_format.ilf_fields; iip->ili_last_fields = iip->ili_fields;
iip->ili_format.ilf_fields = 0; iip->ili_fields = 0;
iip->ili_logged = 1; iip->ili_logged = 1;
xfs_trans_ail_copy_lsn(mp->m_ail, &iip->ili_flush_lsn, xfs_trans_ail_copy_lsn(mp->m_ail, &iip->ili_flush_lsn,
......
...@@ -59,20 +59,20 @@ xfs_inode_item_size( ...@@ -59,20 +59,20 @@ xfs_inode_item_size(
switch (ip->i_d.di_format) { switch (ip->i_d.di_format) {
case XFS_DINODE_FMT_EXTENTS: case XFS_DINODE_FMT_EXTENTS:
if ((iip->ili_format.ilf_fields & XFS_ILOG_DEXT) && if ((iip->ili_fields & XFS_ILOG_DEXT) &&
ip->i_d.di_nextents > 0 && ip->i_d.di_nextents > 0 &&
ip->i_df.if_bytes > 0) ip->i_df.if_bytes > 0)
nvecs++; nvecs++;
break; break;
case XFS_DINODE_FMT_BTREE: case XFS_DINODE_FMT_BTREE:
if ((iip->ili_format.ilf_fields & XFS_ILOG_DBROOT) && if ((iip->ili_fields & XFS_ILOG_DBROOT) &&
ip->i_df.if_broot_bytes > 0) ip->i_df.if_broot_bytes > 0)
nvecs++; nvecs++;
break; break;
case XFS_DINODE_FMT_LOCAL: case XFS_DINODE_FMT_LOCAL:
if ((iip->ili_format.ilf_fields & XFS_ILOG_DDATA) && if ((iip->ili_fields & XFS_ILOG_DDATA) &&
ip->i_df.if_bytes > 0) ip->i_df.if_bytes > 0)
nvecs++; nvecs++;
break; break;
...@@ -95,20 +95,20 @@ xfs_inode_item_size( ...@@ -95,20 +95,20 @@ xfs_inode_item_size(
*/ */
switch (ip->i_d.di_aformat) { switch (ip->i_d.di_aformat) {
case XFS_DINODE_FMT_EXTENTS: case XFS_DINODE_FMT_EXTENTS:
if ((iip->ili_format.ilf_fields & XFS_ILOG_AEXT) && if ((iip->ili_fields & XFS_ILOG_AEXT) &&
ip->i_d.di_anextents > 0 && ip->i_d.di_anextents > 0 &&
ip->i_afp->if_bytes > 0) ip->i_afp->if_bytes > 0)
nvecs++; nvecs++;
break; break;
case XFS_DINODE_FMT_BTREE: case XFS_DINODE_FMT_BTREE:
if ((iip->ili_format.ilf_fields & XFS_ILOG_ABROOT) && if ((iip->ili_fields & XFS_ILOG_ABROOT) &&
ip->i_afp->if_broot_bytes > 0) ip->i_afp->if_broot_bytes > 0)
nvecs++; nvecs++;
break; break;
case XFS_DINODE_FMT_LOCAL: case XFS_DINODE_FMT_LOCAL:
if ((iip->ili_format.ilf_fields & XFS_ILOG_ADATA) && if ((iip->ili_fields & XFS_ILOG_ADATA) &&
ip->i_afp->if_bytes > 0) ip->i_afp->if_bytes > 0)
nvecs++; nvecs++;
break; break;
...@@ -185,7 +185,6 @@ xfs_inode_item_format( ...@@ -185,7 +185,6 @@ xfs_inode_item_format(
vecp->i_type = XLOG_REG_TYPE_ICORE; vecp->i_type = XLOG_REG_TYPE_ICORE;
vecp++; vecp++;
nvecs++; nvecs++;
iip->ili_format.ilf_fields |= XFS_ILOG_CORE;
/* /*
* If this is really an old format inode, then we need to * If this is really an old format inode, then we need to
...@@ -218,11 +217,11 @@ xfs_inode_item_format( ...@@ -218,11 +217,11 @@ xfs_inode_item_format(
switch (ip->i_d.di_format) { switch (ip->i_d.di_format) {
case XFS_DINODE_FMT_EXTENTS: case XFS_DINODE_FMT_EXTENTS:
iip->ili_format.ilf_fields &= iip->ili_fields &=
~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT |
XFS_ILOG_DEV | XFS_ILOG_UUID); XFS_ILOG_DEV | XFS_ILOG_UUID);
if ((iip->ili_format.ilf_fields & XFS_ILOG_DEXT) && if ((iip->ili_fields & XFS_ILOG_DEXT) &&
ip->i_d.di_nextents > 0 && ip->i_d.di_nextents > 0 &&
ip->i_df.if_bytes > 0) { ip->i_df.if_bytes > 0) {
ASSERT(ip->i_df.if_u1.if_extents != NULL); ASSERT(ip->i_df.if_u1.if_extents != NULL);
...@@ -251,16 +250,16 @@ xfs_inode_item_format( ...@@ -251,16 +250,16 @@ xfs_inode_item_format(
vecp++; vecp++;
nvecs++; nvecs++;
} else { } else {
iip->ili_format.ilf_fields &= ~XFS_ILOG_DEXT; iip->ili_fields &= ~XFS_ILOG_DEXT;
} }
break; break;
case XFS_DINODE_FMT_BTREE: case XFS_DINODE_FMT_BTREE:
iip->ili_format.ilf_fields &= iip->ili_fields &=
~(XFS_ILOG_DDATA | XFS_ILOG_DEXT | ~(XFS_ILOG_DDATA | XFS_ILOG_DEXT |
XFS_ILOG_DEV | XFS_ILOG_UUID); XFS_ILOG_DEV | XFS_ILOG_UUID);
if ((iip->ili_format.ilf_fields & XFS_ILOG_DBROOT) && if ((iip->ili_fields & XFS_ILOG_DBROOT) &&
ip->i_df.if_broot_bytes > 0) { ip->i_df.if_broot_bytes > 0) {
ASSERT(ip->i_df.if_broot != NULL); ASSERT(ip->i_df.if_broot != NULL);
vecp->i_addr = ip->i_df.if_broot; vecp->i_addr = ip->i_df.if_broot;
...@@ -270,7 +269,7 @@ xfs_inode_item_format( ...@@ -270,7 +269,7 @@ xfs_inode_item_format(
nvecs++; nvecs++;
iip->ili_format.ilf_dsize = ip->i_df.if_broot_bytes; iip->ili_format.ilf_dsize = ip->i_df.if_broot_bytes;
} else { } else {
ASSERT(!(iip->ili_format.ilf_fields & ASSERT(!(iip->ili_fields &
XFS_ILOG_DBROOT)); XFS_ILOG_DBROOT));
#ifdef XFS_TRANS_DEBUG #ifdef XFS_TRANS_DEBUG
if (iip->ili_root_size > 0) { if (iip->ili_root_size > 0) {
...@@ -283,15 +282,15 @@ xfs_inode_item_format( ...@@ -283,15 +282,15 @@ xfs_inode_item_format(
ASSERT(ip->i_df.if_broot_bytes == 0); ASSERT(ip->i_df.if_broot_bytes == 0);
} }
#endif #endif
iip->ili_format.ilf_fields &= ~XFS_ILOG_DBROOT; iip->ili_fields &= ~XFS_ILOG_DBROOT;
} }
break; break;
case XFS_DINODE_FMT_LOCAL: case XFS_DINODE_FMT_LOCAL:
iip->ili_format.ilf_fields &= iip->ili_fields &=
~(XFS_ILOG_DEXT | XFS_ILOG_DBROOT | ~(XFS_ILOG_DEXT | XFS_ILOG_DBROOT |
XFS_ILOG_DEV | XFS_ILOG_UUID); XFS_ILOG_DEV | XFS_ILOG_UUID);
if ((iip->ili_format.ilf_fields & XFS_ILOG_DDATA) && if ((iip->ili_fields & XFS_ILOG_DDATA) &&
ip->i_df.if_bytes > 0) { ip->i_df.if_bytes > 0) {
ASSERT(ip->i_df.if_u1.if_data != NULL); ASSERT(ip->i_df.if_u1.if_data != NULL);
ASSERT(ip->i_d.di_size > 0); ASSERT(ip->i_d.di_size > 0);
...@@ -311,25 +310,25 @@ xfs_inode_item_format( ...@@ -311,25 +310,25 @@ xfs_inode_item_format(
nvecs++; nvecs++;
iip->ili_format.ilf_dsize = (unsigned)data_bytes; iip->ili_format.ilf_dsize = (unsigned)data_bytes;
} else { } else {
iip->ili_format.ilf_fields &= ~XFS_ILOG_DDATA; iip->ili_fields &= ~XFS_ILOG_DDATA;
} }
break; break;
case XFS_DINODE_FMT_DEV: case XFS_DINODE_FMT_DEV:
iip->ili_format.ilf_fields &= iip->ili_fields &=
~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT |
XFS_ILOG_DEXT | XFS_ILOG_UUID); XFS_ILOG_DEXT | XFS_ILOG_UUID);
if (iip->ili_format.ilf_fields & XFS_ILOG_DEV) { if (iip->ili_fields & XFS_ILOG_DEV) {
iip->ili_format.ilf_u.ilfu_rdev = iip->ili_format.ilf_u.ilfu_rdev =
ip->i_df.if_u2.if_rdev; ip->i_df.if_u2.if_rdev;
} }
break; break;
case XFS_DINODE_FMT_UUID: case XFS_DINODE_FMT_UUID:
iip->ili_format.ilf_fields &= iip->ili_fields &=
~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT | ~(XFS_ILOG_DDATA | XFS_ILOG_DBROOT |
XFS_ILOG_DEXT | XFS_ILOG_DEV); XFS_ILOG_DEXT | XFS_ILOG_DEV);
if (iip->ili_format.ilf_fields & XFS_ILOG_UUID) { if (iip->ili_fields & XFS_ILOG_UUID) {
iip->ili_format.ilf_u.ilfu_uuid = iip->ili_format.ilf_u.ilfu_uuid =
ip->i_df.if_u2.if_uuid; ip->i_df.if_u2.if_uuid;
} }
...@@ -344,18 +343,17 @@ xfs_inode_item_format( ...@@ -344,18 +343,17 @@ xfs_inode_item_format(
* If there are no attributes associated with the file, then we're done. * If there are no attributes associated with the file, then we're done.
*/ */
if (!XFS_IFORK_Q(ip)) { if (!XFS_IFORK_Q(ip)) {
iip->ili_format.ilf_size = nvecs; iip->ili_fields &=
iip->ili_format.ilf_fields &=
~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT | XFS_ILOG_AEXT); ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT | XFS_ILOG_AEXT);
return; goto out;
} }
switch (ip->i_d.di_aformat) { switch (ip->i_d.di_aformat) {
case XFS_DINODE_FMT_EXTENTS: case XFS_DINODE_FMT_EXTENTS:
iip->ili_format.ilf_fields &= iip->ili_fields &=
~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT); ~(XFS_ILOG_ADATA | XFS_ILOG_ABROOT);
if ((iip->ili_format.ilf_fields & XFS_ILOG_AEXT) && if ((iip->ili_fields & XFS_ILOG_AEXT) &&
ip->i_d.di_anextents > 0 && ip->i_d.di_anextents > 0 &&
ip->i_afp->if_bytes > 0) { ip->i_afp->if_bytes > 0) {
ASSERT(ip->i_afp->if_bytes / sizeof(xfs_bmbt_rec_t) == ASSERT(ip->i_afp->if_bytes / sizeof(xfs_bmbt_rec_t) ==
...@@ -378,15 +376,15 @@ xfs_inode_item_format( ...@@ -378,15 +376,15 @@ xfs_inode_item_format(
vecp++; vecp++;
nvecs++; nvecs++;
} else { } else {
iip->ili_format.ilf_fields &= ~XFS_ILOG_AEXT; iip->ili_fields &= ~XFS_ILOG_AEXT;
} }
break; break;
case XFS_DINODE_FMT_BTREE: case XFS_DINODE_FMT_BTREE:
iip->ili_format.ilf_fields &= iip->ili_fields &=
~(XFS_ILOG_ADATA | XFS_ILOG_AEXT); ~(XFS_ILOG_ADATA | XFS_ILOG_AEXT);
if ((iip->ili_format.ilf_fields & XFS_ILOG_ABROOT) && if ((iip->ili_fields & XFS_ILOG_ABROOT) &&
ip->i_afp->if_broot_bytes > 0) { ip->i_afp->if_broot_bytes > 0) {
ASSERT(ip->i_afp->if_broot != NULL); ASSERT(ip->i_afp->if_broot != NULL);
...@@ -397,15 +395,15 @@ xfs_inode_item_format( ...@@ -397,15 +395,15 @@ xfs_inode_item_format(
nvecs++; nvecs++;
iip->ili_format.ilf_asize = ip->i_afp->if_broot_bytes; iip->ili_format.ilf_asize = ip->i_afp->if_broot_bytes;
} else { } else {
iip->ili_format.ilf_fields &= ~XFS_ILOG_ABROOT; iip->ili_fields &= ~XFS_ILOG_ABROOT;
} }
break; break;
case XFS_DINODE_FMT_LOCAL: case XFS_DINODE_FMT_LOCAL:
iip->ili_format.ilf_fields &= iip->ili_fields &=
~(XFS_ILOG_AEXT | XFS_ILOG_ABROOT); ~(XFS_ILOG_AEXT | XFS_ILOG_ABROOT);
if ((iip->ili_format.ilf_fields & XFS_ILOG_ADATA) && if ((iip->ili_fields & XFS_ILOG_ADATA) &&
ip->i_afp->if_bytes > 0) { ip->i_afp->if_bytes > 0) {
ASSERT(ip->i_afp->if_u1.if_data != NULL); ASSERT(ip->i_afp->if_u1.if_data != NULL);
...@@ -424,7 +422,7 @@ xfs_inode_item_format( ...@@ -424,7 +422,7 @@ xfs_inode_item_format(
nvecs++; nvecs++;
iip->ili_format.ilf_asize = (unsigned)data_bytes; iip->ili_format.ilf_asize = (unsigned)data_bytes;
} else { } else {
iip->ili_format.ilf_fields &= ~XFS_ILOG_ADATA; iip->ili_fields &= ~XFS_ILOG_ADATA;
} }
break; break;
...@@ -433,6 +431,14 @@ xfs_inode_item_format( ...@@ -433,6 +431,14 @@ xfs_inode_item_format(
break; break;
} }
out:
/*
* Now update the log format that goes out to disk from the in-core
* values. We always write the inode core to make the arithmetic
* games in recovery easier, which isn't a big deal as just about any
* transaction would dirty it anyway.
*/
iip->ili_format.ilf_fields = XFS_ILOG_CORE | iip->ili_fields;
iip->ili_format.ilf_size = nvecs; iip->ili_format.ilf_size = nvecs;
} }
...@@ -517,7 +523,7 @@ xfs_inode_item_trylock( ...@@ -517,7 +523,7 @@ xfs_inode_item_trylock(
#ifdef DEBUG #ifdef DEBUG
if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) { if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {
ASSERT(iip->ili_format.ilf_fields != 0); ASSERT(iip->ili_fields != 0);
ASSERT(iip->ili_logged == 0); ASSERT(iip->ili_logged == 0);
ASSERT(lip->li_flags & XFS_LI_IN_AIL); ASSERT(lip->li_flags & XFS_LI_IN_AIL);
} }
...@@ -549,7 +555,7 @@ xfs_inode_item_unlock( ...@@ -549,7 +555,7 @@ xfs_inode_item_unlock(
if (iip->ili_extents_buf != NULL) { if (iip->ili_extents_buf != NULL) {
ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS); ASSERT(ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS);
ASSERT(ip->i_d.di_nextents > 0); ASSERT(ip->i_d.di_nextents > 0);
ASSERT(iip->ili_format.ilf_fields & XFS_ILOG_DEXT); ASSERT(iip->ili_fields & XFS_ILOG_DEXT);
ASSERT(ip->i_df.if_bytes > 0); ASSERT(ip->i_df.if_bytes > 0);
kmem_free(iip->ili_extents_buf); kmem_free(iip->ili_extents_buf);
iip->ili_extents_buf = NULL; iip->ili_extents_buf = NULL;
...@@ -557,7 +563,7 @@ xfs_inode_item_unlock( ...@@ -557,7 +563,7 @@ xfs_inode_item_unlock(
if (iip->ili_aextents_buf != NULL) { if (iip->ili_aextents_buf != NULL) {
ASSERT(ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS); ASSERT(ip->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS);
ASSERT(ip->i_d.di_anextents > 0); ASSERT(ip->i_d.di_anextents > 0);
ASSERT(iip->ili_format.ilf_fields & XFS_ILOG_AEXT); ASSERT(iip->ili_fields & XFS_ILOG_AEXT);
ASSERT(ip->i_afp->if_bytes > 0); ASSERT(ip->i_afp->if_bytes > 0);
kmem_free(iip->ili_aextents_buf); kmem_free(iip->ili_aextents_buf);
iip->ili_aextents_buf = NULL; iip->ili_aextents_buf = NULL;
...@@ -672,8 +678,7 @@ xfs_inode_item_push( ...@@ -672,8 +678,7 @@ xfs_inode_item_push(
* lock without sleeping, then there must not have been * lock without sleeping, then there must not have been
* anyone in the process of flushing the inode. * anyone in the process of flushing the inode.
*/ */
ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || iip->ili_fields != 0);
iip->ili_format.ilf_fields != 0);
/* /*
* Push the inode to it's backing buffer. This will not remove the * Push the inode to it's backing buffer. This will not remove the
...@@ -896,7 +901,7 @@ xfs_iflush_abort( ...@@ -896,7 +901,7 @@ xfs_iflush_abort(
* Clear the inode logging fields so no more flushes are * Clear the inode logging fields so no more flushes are
* attempted. * attempted.
*/ */
iip->ili_format.ilf_fields = 0; iip->ili_fields = 0;
} }
/* /*
* Release the inode's flush lock since we're done with it. * Release the inode's flush lock since we're done with it.
......
...@@ -134,6 +134,7 @@ typedef struct xfs_inode_log_item { ...@@ -134,6 +134,7 @@ typedef struct xfs_inode_log_item {
unsigned short ili_lock_flags; /* lock flags */ unsigned short ili_lock_flags; /* lock flags */
unsigned short ili_logged; /* flushed logged data */ unsigned short ili_logged; /* flushed logged data */
unsigned int ili_last_fields; /* fields when flushed */ unsigned int ili_last_fields; /* fields when flushed */
unsigned int ili_fields; /* fields to be logged */
struct xfs_bmbt_rec *ili_extents_buf; /* array of logged struct xfs_bmbt_rec *ili_extents_buf; /* array of logged
data exts */ data exts */
struct xfs_bmbt_rec *ili_aextents_buf; /* array of logged struct xfs_bmbt_rec *ili_aextents_buf; /* array of logged
...@@ -148,8 +149,7 @@ typedef struct xfs_inode_log_item { ...@@ -148,8 +149,7 @@ typedef struct xfs_inode_log_item {
static inline int xfs_inode_clean(xfs_inode_t *ip) static inline int xfs_inode_clean(xfs_inode_t *ip)
{ {
return !ip->i_itemp || return !ip->i_itemp || !(ip->i_itemp->ili_fields & XFS_ILOG_ALL);
!(ip->i_itemp->ili_format.ilf_fields & XFS_ILOG_ALL);
} }
extern void xfs_inode_item_init(struct xfs_inode *, struct xfs_mount *); extern void xfs_inode_item_init(struct xfs_inode *, struct xfs_mount *);
......
...@@ -130,12 +130,12 @@ xfs_trans_log_inode( ...@@ -130,12 +130,12 @@ xfs_trans_log_inode(
/* /*
* Always OR in the bits from the ili_last_fields field. * Always OR in the bits from the ili_last_fields field.
* This is to coordinate with the xfs_iflush() and xfs_iflush_done() * This is to coordinate with the xfs_iflush() and xfs_iflush_done()
* routines in the eventual clearing of the ilf_fields bits. * routines in the eventual clearing of the ili_fields bits.
* See the big comment in xfs_iflush() for an explanation of * See the big comment in xfs_iflush() for an explanation of
* this coordination mechanism. * this coordination mechanism.
*/ */
flags |= ip->i_itemp->ili_last_fields; flags |= ip->i_itemp->ili_last_fields;
ip->i_itemp->ili_format.ilf_fields |= flags; ip->i_itemp->ili_fields |= flags;
} }
#ifdef XFS_TRANS_DEBUG #ifdef XFS_TRANS_DEBUG
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册