Skip to content

Commit

Permalink
libxfs: v3 inodes are only valid on crc-enabled filesystems
Browse files Browse the repository at this point in the history
xfs_repair was not detecting that version 3 inodes are invalid for
for non-CRC filesystems. The result is specific inode corruptions go
undetected and hence aren't repaired if only the version number is
out of range.

The core of the problem is that the XFS_DINODE_GOOD_VERSION() macro
doesn't know that valid inode versions are dependent on a superblock
version number. Fix this in libxfs, and propagate the new function
out into the rest of xfsprogs to fix the issue.

[Darrick: port to kernel from xfsprogs]

Reported-by: Leslie Rhorer <lrhorer@mygrande.net>
Signed-off-by: Roger Willcocks <roger@filmlight.ltd.uk>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
  • Loading branch information
rkwwgit authored and dchinner committed Oct 20, 2016
1 parent 58d7896 commit 8cdcc81
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 2 deletions.
1 change: 0 additions & 1 deletion fs/xfs/libxfs/xfs_format.h
Original file line number Diff line number Diff line change
Expand Up @@ -865,7 +865,6 @@ typedef struct xfs_timestamp {
* padding field for v3 inodes.
*/
#define XFS_DINODE_MAGIC 0x494e /* 'IN' */
#define XFS_DINODE_GOOD_VERSION(v) ((v) >= 1 && (v) <= 3)
typedef struct xfs_dinode {
__be16 di_magic; /* inode magic # = XFS_DINODE_MAGIC */
__be16 di_mode; /* mode and type of file */
Expand Down
13 changes: 12 additions & 1 deletion fs/xfs/libxfs/xfs_inode_buf.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,17 @@ xfs_inobp_check(
}
#endif

bool
xfs_dinode_good_version(
struct xfs_mount *mp,
__u8 version)
{
if (xfs_sb_version_hascrc(&mp->m_sb))
return version == 3;

return version == 1 || version == 2;
}

/*
* If we are doing readahead on an inode buffer, we might be in log recovery
* reading an inode allocation buffer that hasn't yet been replayed, and hence
Expand Down Expand Up @@ -91,7 +102,7 @@ xfs_inode_buf_verify(

dip = xfs_buf_offset(bp, (i << mp->m_sb.sb_inodelog));
di_ok = dip->di_magic == cpu_to_be16(XFS_DINODE_MAGIC) &&
XFS_DINODE_GOOD_VERSION(dip->di_version);
xfs_dinode_good_version(mp, dip->di_version);
if (unlikely(XFS_TEST_ERROR(!di_ok, mp,
XFS_ERRTAG_ITOBP_INOTOBP,
XFS_RANDOM_ITOBP_INOTOBP))) {
Expand Down
2 changes: 2 additions & 0 deletions fs/xfs/libxfs/xfs_inode_buf.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ void xfs_inode_from_disk(struct xfs_inode *ip, struct xfs_dinode *from);
void xfs_log_dinode_to_disk(struct xfs_log_dinode *from,
struct xfs_dinode *to);

bool xfs_dinode_good_version(struct xfs_mount *mp, __u8 version);

#if defined(DEBUG)
void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *);
#else
Expand Down

0 comments on commit 8cdcc81

Please sign in to comment.