From: Brian Foster <bfoster@redhat.com>
To: Dave Chinner <david@fromorbit.com>
Cc: bpm@sgi.com, xfs@oss.sgi.com
Subject: Re: [PATCH 2/2] xfs: inode unlinked list needs to recalculate the inode CRC
Date: Thu, 30 May 2013 10:17:47 -0400 [thread overview]
Message-ID: <51A75F8B.8000507@redhat.com> (raw)
In-Reply-To: <1369773373-26697-3-git-send-email-david@fromorbit.com>
On 05/28/2013 04:36 PM, Dave Chinner wrote:
> From: Dave Chinner <dchinner@redhat.com>
>
> The inode unlinked list manipulations operate directly on the inode
> buffer, and so bypass the inode CRC calculation mechanisms. Hence an
> inode on the unlinked list has an invalid CRC. Fix this by
> recalculating the CRC whenever we modify an unlinked list pointer in
> an inode, ncluding during log recovery. This is trivial to do and
> results in unlinked list operations always leaving a consistent
> inode in the buffer.
>
> Signed-off-by: Dave Chinner <dchinner@redhat.com>
> ---
> fs/xfs/xfs_inode.c | 42 ++++++++++++++++++++++++++++++++++++++----
> fs/xfs/xfs_log_recover.c | 9 +++++++++
> 2 files changed, 47 insertions(+), 4 deletions(-)
>
> diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
> index efbe1ac..2d993e7 100644
> --- a/fs/xfs/xfs_inode.c
> +++ b/fs/xfs/xfs_inode.c
> @@ -1579,6 +1579,23 @@ out_bmap_cancel:
> }
>
> /*
> + * Helper function to calculate range of the inode to log and recalculate the
> + * on-disk inode crc if necessary.
> + */
> +static int
> +xfs_iunlink_dinode_calc_crc(
> + struct xfs_mount *mp,
> + struct xfs_dinode *dip)
> +{
> + if (dip->di_version < 3)
> + return sizeof(xfs_agino_t);
> +
> + xfs_dinode_calc_crc(mp, dip);
> + return offsetof(struct xfs_dinode, di_changecount) -
> + offsetof(struct xfs_dinode, di_next_unlinked);
> +}
> +
So we've added a new helper, the return value for which is either the
size of an inode number or an inode number + crc, depending on format. I
also notice that the return value doesn't appear to be used anywhere
this helper is called.
> +/*
> * 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
> * will be pulled from this list when the inode is freed.
> @@ -1638,10 +1655,15 @@ xfs_iunlink(
> dip->di_next_unlinked = agi->agi_unlinked[bucket_index];
> offset = ip->i_imap.im_boffset +
> offsetof(xfs_dinode_t, di_next_unlinked);
> +
> + /* need to recalc the inode CRC if appropriate */
> + xfs_iunlink_dinode_calc_crc(mp, dip);
> +
> xfs_trans_inode_buf(tp, ibp);
> xfs_trans_log_buf(tp, ibp, offset,
> - (offset + sizeof(xfs_agino_t) - 1));
> + offset + sizeof(xfs_agino_t) - 1);
> xfs_inobp_check(mp, ibp);
> +
> }
So IIUC, offset is set to the offset of the di_next_unlinked value of
this inode in the backing buffer of the inode (which we've just updated
directly via dip).
We call the helper to update the CRC then call xfs_trans_log_buf() to
log a range of the buffer. From the original code, I surmise that we're
logging the range that represents the di_next_unlinked value and from
the addition of the helper, I surmise we intend to now include the crc
in that logged region.
But we haven't utilized the return value and I'm speculating on the
intent here. So I see that we're updating the CRC, but is it actually
logged? Perhaps I'm missing something, but if so, then why even have the
xfs_iunlink_dinode_calc_crc() helper?
/me goes back to read the original 9/9 and followup:
http://oss.sgi.com/archives/xfs/2013-05/msg00867.html
OK, so in that case, perhaps the helper is now unnecessary and we could
just call xfs_dinode_calc_crc()?
BTW, I was also going to ask here whether the fact that we update the
CRC on recovery rather than logging it exposed items in the log to risk
if they happened to become corrupted before that update occurs, but
IIUC, we're still protected in that recovery itself should validate the
existing on-disk CRC prior to the update. Correct?
Brian
>
> /*
> @@ -1723,9 +1745,13 @@ xfs_iunlink_remove(
> dip->di_next_unlinked = cpu_to_be32(NULLAGINO);
> offset = ip->i_imap.im_boffset +
> offsetof(xfs_dinode_t, di_next_unlinked);
> +
> + /* need to recalc the inode CRC if appropriate */
> + xfs_iunlink_dinode_calc_crc(mp, dip);
> +
> xfs_trans_inode_buf(tp, ibp);
> xfs_trans_log_buf(tp, ibp, offset,
> - (offset + sizeof(xfs_agino_t) - 1));
> + offset + sizeof(xfs_agino_t) - 1);
> xfs_inobp_check(mp, ibp);
> } else {
> xfs_trans_brelse(tp, ibp);
> @@ -1796,9 +1822,13 @@ xfs_iunlink_remove(
> dip->di_next_unlinked = cpu_to_be32(NULLAGINO);
> offset = ip->i_imap.im_boffset +
> offsetof(xfs_dinode_t, di_next_unlinked);
> +
> + /* need to recalc the inode CRC if appropriate */
> + xfs_iunlink_dinode_calc_crc(mp, dip);
> +
> xfs_trans_inode_buf(tp, ibp);
> xfs_trans_log_buf(tp, ibp, offset,
> - (offset + sizeof(xfs_agino_t) - 1));
> + offset + sizeof(xfs_agino_t) - 1);
> xfs_inobp_check(mp, ibp);
> } else {
> xfs_trans_brelse(tp, ibp);
> @@ -1809,9 +1839,13 @@ xfs_iunlink_remove(
> last_dip->di_next_unlinked = cpu_to_be32(next_agino);
> ASSERT(next_agino != 0);
> offset = last_offset + offsetof(xfs_dinode_t, di_next_unlinked);
> +
> + /* need to recalc the inode CRC if appropriate */
> + xfs_iunlink_dinode_calc_crc(mp, dip);
> +
> xfs_trans_inode_buf(tp, last_ibp);
> xfs_trans_log_buf(tp, last_ibp, offset,
> - (offset + sizeof(xfs_agino_t) - 1));
> + offset + sizeof(xfs_agino_t) - 1);
> xfs_inobp_check(mp, last_ibp);
> }
> return 0;
> diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
> index 83088d9..45a85ff 100644
> --- a/fs/xfs/xfs_log_recover.c
> +++ b/fs/xfs/xfs_log_recover.c
> @@ -1912,6 +1912,15 @@ xlog_recover_do_inode_buffer(
> buffer_nextp = (xfs_agino_t *)xfs_buf_offset(bp,
> next_unlinked_offset);
> *buffer_nextp = *logged_nextp;
> +
> + /*
> + * If necessary, recalculate the CRC in the on-disk inode. We
> + * have to leave the inode in a consistent state for whoever
> + * reads it next....
> + */
> + xfs_dinode_calc_crc(mp, (struct xfs_dinode *)
> + xfs_buf_offset(bp, i * mp->m_sb.sb_inodesize));
> +
> }
>
> return 0;
>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
next prev parent reply other threads:[~2013-05-30 14:20 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-05-27 6:38 [PATH 0/9] xfs: fixes for 3.10-rc4 Dave Chinner
2013-05-27 6:38 ` [PATCH 1/9] xfs: don't emit v5 superblock warnings on write Dave Chinner
2013-05-29 16:39 ` Brian Foster
2013-05-30 17:49 ` Ben Myers
2013-06-11 6:05 ` Dave Chinner
2013-06-11 21:29 ` Ben Myers
2013-05-27 6:38 ` [PATCH 2/9] xfs: fix incorrect remote symlink block count Dave Chinner
2013-05-29 16:39 ` Brian Foster
2013-05-30 0:46 ` Dave Chinner
2013-05-30 17:49 ` Ben Myers
2013-05-27 6:38 ` [PATCH 3/9] xfs: increase number of ACL entries for V5 superblocks Dave Chinner
2013-05-29 16:40 ` Brian Foster
2013-05-27 6:38 ` [PATCH 4/9] xfs: rework dquot CRCs Dave Chinner
2013-05-29 18:58 ` Brian Foster
2013-05-30 1:00 ` Dave Chinner
2013-05-30 12:02 ` Brian Foster
2013-06-03 4:12 ` Dave Chinner
2013-05-27 6:38 ` [PATCH 5/9] xfs: fix split buffer vector log recovery support Dave Chinner
2013-05-29 19:21 ` Mark Tinguely
2013-05-30 17:49 ` Ben Myers
2013-05-27 6:38 ` [PATCH 6/9] xfs: disable swap extents ioctl on CRC enabled filesystems Dave Chinner
2013-05-28 21:49 ` Ben Myers
2013-05-30 1:07 ` Dave Chinner
2013-05-29 21:06 ` Brian Foster
2013-05-30 17:56 ` Ben Myers
2013-05-27 6:38 ` [PATCH 7/9] xfs: kill suid/sgid through the truncate path Dave Chinner
2013-05-30 14:17 ` Brian Foster
2013-05-30 15:52 ` Ben Myers
2013-05-30 16:02 ` Brian Foster
2013-05-30 17:07 ` Ben Myers
2013-05-27 6:38 ` [PATCH 8/9] xfs: add fsgeom flag for v5 superblock support Dave Chinner
2013-05-29 15:10 ` Eric Sandeen
2013-05-29 21:43 ` Ben Myers
2013-05-29 21:47 ` Ben Myers
2013-05-30 1:28 ` Dave Chinner
2013-05-30 1:11 ` Dave Chinner
2013-05-30 14:17 ` Brian Foster
2013-05-30 17:57 ` Ben Myers
2013-05-27 6:38 ` [PATCH 9/9] xfs: inode unlinked list needs to recalculate the inode CRC Dave Chinner
2013-05-28 11:51 ` Dave Chinner
2013-05-28 20:36 ` [PATCH 9a,9b v2, replacements] xfs: unlinked list crcs Dave Chinner
2013-05-28 20:36 ` [PATCH 1/2] xfs: fix log recovery transaction item reordering Dave Chinner
2013-05-28 20:36 ` [PATCH 2/2] xfs: inode unlinked list needs to recalculate the inode CRC Dave Chinner
2013-05-30 14:17 ` Brian Foster [this message]
2013-05-30 20:27 ` Dave Chinner
2013-05-28 8:37 ` [PATCH 10/9] xfs: fix dir3 freespace block corruption Dave Chinner
2013-05-30 19:15 ` Ben Myers
2013-05-31 21:54 ` Ben Myers
2013-05-28 17:56 ` [PATH 0/9] xfs: fixes for 3.10-rc4 Ben Myers
2013-05-28 23:54 ` Dave Chinner
2013-05-29 19:01 ` Ben Myers
2013-05-29 19:27 ` Eric Sandeen
2013-05-29 19:45 ` Ben Myers
2013-05-28 21:27 ` [PATCH 11/9] xfs: fix remote attribute invalidation for a leaf Dave Chinner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=51A75F8B.8000507@redhat.com \
--to=bfoster@redhat.com \
--cc=bpm@sgi.com \
--cc=david@fromorbit.com \
--cc=xfs@oss.sgi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox