@ -304,9 +304,8 @@ STATIC int
xfs_mount_validate_sb (
xfs_mount_t * mp ,
xfs_sb_t * sbp ,
int flag s)
bool check_inprogres s)
{
int loud = ! ( flags & XFS_MFSI_QUIET ) ;
/*
* If the log device and data device have the
@ -316,21 +315,18 @@ xfs_mount_validate_sb(
* a volume filesystem in a non - volume manner .
*/
if ( sbp - > sb_magicnum ! = XFS_SB_MAGIC ) {
if ( loud )
xfs_warn ( mp , " bad magic number " ) ;
xfs_warn ( mp , " bad magic number " ) ;
return XFS_ERROR ( EWRONGFS ) ;
}
if ( ! xfs_sb_good_version ( sbp ) ) {
if ( loud )
xfs_warn ( mp , " bad version " ) ;
xfs_warn ( mp , " bad version " ) ;
return XFS_ERROR ( EWRONGFS ) ;
}
if ( unlikely (
sbp - > sb_logstart = = 0 & & mp - > m_logdev_targp = = mp - > m_ddev_targp ) ) {
if ( loud )
xfs_warn ( mp ,
xfs_warn ( mp ,
" filesystem is marked as having an external log; "
" specify logdev on the mount command line. " ) ;
return XFS_ERROR ( EINVAL ) ;
@ -338,8 +334,7 @@ xfs_mount_validate_sb(
if ( unlikely (
sbp - > sb_logstart ! = 0 & & mp - > m_logdev_targp ! = mp - > m_ddev_targp ) ) {
if ( loud )
xfs_warn ( mp ,
xfs_warn ( mp ,
" filesystem is marked as having an internal log; "
" do not specify logdev on the mount command line. " ) ;
return XFS_ERROR ( EINVAL ) ;
@ -373,8 +368,7 @@ xfs_mount_validate_sb(
sbp - > sb_dblocks = = 0 | |
sbp - > sb_dblocks > XFS_MAX_DBLOCKS ( sbp ) | |
sbp - > sb_dblocks < XFS_MIN_DBLOCKS ( sbp ) ) ) {
if ( loud )
XFS_CORRUPTION_ERROR ( " SB sanity check failed " ,
XFS_CORRUPTION_ERROR ( " SB sanity check failed " ,
XFS_ERRLEVEL_LOW , mp , sbp ) ;
return XFS_ERROR ( EFSCORRUPTED ) ;
}
@ -383,12 +377,10 @@ xfs_mount_validate_sb(
* Until this is fixed only page - sized or smaller data blocks work .
*/
if ( unlikely ( sbp - > sb_blocksize > PAGE_SIZE ) ) {
if ( loud ) {
xfs_warn ( mp ,
xfs_warn ( mp ,
" File system with blocksize %d bytes. "
" Only pagesize (%ld) or less will currently work. " ,
sbp - > sb_blocksize , PAGE_SIZE ) ;
}
return XFS_ERROR ( ENOSYS ) ;
}
@ -402,23 +394,20 @@ xfs_mount_validate_sb(
case 2048 :
break ;
default :
if ( loud )
xfs_warn ( mp , " inode size of %d bytes not supported " ,
xfs_warn ( mp , " inode size of %d bytes not supported " ,
sbp - > sb_inodesize ) ;
return XFS_ERROR ( ENOSYS ) ;
}
if ( xfs_sb_validate_fsb_count ( sbp , sbp - > sb_dblocks ) | |
xfs_sb_validate_fsb_count ( sbp , sbp - > sb_rblocks ) ) {
if ( loud )
xfs_warn ( mp ,
xfs_warn ( mp ,
" file system too large to be mounted on this system. " ) ;
return XFS_ERROR ( EFBIG ) ;
}
if ( unlikely ( sbp - > sb_inprogress ) ) {
if ( loud )
xfs_warn ( mp , " file system busy " ) ;
if ( check_inprogress & & sbp - > sb_inprogress ) {
xfs_warn ( mp , " Offline file system operation in progress! " ) ;
return XFS_ERROR ( EFSCORRUPTED ) ;
}
@ -426,9 +415,7 @@ xfs_mount_validate_sb(
* Version 1 directory format has never worked on Linux .
*/
if ( unlikely ( ! xfs_sb_version_hasdirv2 ( sbp ) ) ) {
if ( loud )
xfs_warn ( mp ,
" file system using version 1 directory format " ) ;
xfs_warn ( mp , " file system using version 1 directory format " ) ;
return XFS_ERROR ( ENOSYS ) ;
}
@ -521,11 +508,9 @@ out_unwind:
void
xfs_sb_from_disk (
struct xfs_mount * mp ,
struct xfs_sb * to ,
xfs_dsb_t * from )
{
struct xfs_sb * to = & mp - > m_sb ;
to - > sb_magicnum = be32_to_cpu ( from - > sb_magicnum ) ;
to - > sb_blocksize = be32_to_cpu ( from - > sb_blocksize ) ;
to - > sb_dblocks = be64_to_cpu ( from - > sb_dblocks ) ;
@ -627,6 +612,50 @@ xfs_sb_to_disk(
}
}
void
xfs_sb_read_verify (
struct xfs_buf * bp )
{
struct xfs_mount * mp = bp - > b_target - > bt_mount ;
struct xfs_sb sb ;
int error ;
xfs_sb_from_disk ( & sb , XFS_BUF_TO_SBP ( bp ) ) ;
/*
* Only check the in progress field for the primary superblock as
* mkfs . xfs doesn ' t clear it from secondary superblocks .
*/
error = xfs_mount_validate_sb ( mp , & sb , bp - > b_bn = = XFS_SB_DADDR ) ;
if ( error )
xfs_buf_ioerror ( bp , error ) ;
bp - > b_iodone = NULL ;
xfs_buf_ioend ( bp , 0 ) ;
}
/*
* We may be probed for a filesystem match , so we may not want to emit
* messages when the superblock buffer is not actually an XFS superblock .
* If we find an XFS superblock , the run a normal , noisy mount because we are
* really going to mount it and want to know about errors .
*/
void
xfs_sb_quiet_read_verify (
struct xfs_buf * bp )
{
struct xfs_sb sb ;
xfs_sb_from_disk ( & sb , XFS_BUF_TO_SBP ( bp ) ) ;
if ( sb . sb_magicnum = = XFS_SB_MAGIC ) {
/* XFS filesystem, verify noisily! */
xfs_sb_read_verify ( bp ) ;
return ;
}
/* quietly fail */
xfs_buf_ioerror ( bp , EFSCORRUPTED ) ;
}
/*
* xfs_readsb
*
@ -652,7 +681,9 @@ xfs_readsb(xfs_mount_t *mp, int flags)
reread :
bp = xfs_buf_read_uncached ( mp - > m_ddev_targp , XFS_SB_DADDR ,
BTOBB ( sector_size ) , 0 , NULL ) ;
BTOBB ( sector_size ) , 0 ,
loud ? xfs_sb_read_verify
: xfs_sb_quiet_read_verify ) ;
if ( ! bp ) {
if ( loud )
xfs_warn ( mp , " SB buffer read failed " ) ;
@ -667,15 +698,8 @@ reread:
/*
* Initialize the mount structure from the superblock .
* But first do some basic consistency checking .
*/
xfs_sb_from_disk ( mp , XFS_BUF_TO_SBP ( bp ) ) ;
error = xfs_mount_validate_sb ( mp , & ( mp - > m_sb ) , flags ) ;
if ( error ) {
if ( loud )
xfs_warn ( mp , " SB validate failed " ) ;
goto release_buf ;
}
xfs_sb_from_disk ( & mp - > m_sb , XFS_BUF_TO_SBP ( bp ) ) ;
/*
* We must be able to do sector - sized and sector - aligned IO .