2018-06-06 05:42:14 +03:00
// SPDX-License-Identifier: GPL-2.0+
2017-10-18 07:37:45 +03:00
/*
* Copyright ( C ) 2017 Oracle . All Rights Reserved .
* Author : Darrick J . Wong < darrick . wong @ oracle . com >
*/
# include "xfs.h"
# include "xfs_fs.h"
# include "xfs_shared.h"
# include "xfs_format.h"
# include "xfs_trans_resv.h"
# include "xfs_mount.h"
# include "xfs_log_format.h"
# include "xfs_inode.h"
# include "xfs_symlink.h"
# include "scrub/scrub.h"
# include "scrub/common.h"
/* Set us up to scrub a symbolic link. */
int
2018-07-19 22:29:11 +03:00
xchk_setup_symlink (
2021-04-08 03:59:39 +03:00
struct xfs_scrub * sc )
2017-10-18 07:37:45 +03:00
{
/* Allocate the buffer without the inode lock held. */
2020-09-01 21:47:12 +03:00
sc - > buf = kvzalloc ( XFS_SYMLINK_MAXLEN + 1 , GFP_KERNEL ) ;
2017-10-18 07:37:45 +03:00
if ( ! sc - > buf )
return - ENOMEM ;
2021-04-08 03:59:39 +03:00
return xchk_setup_inode_contents ( sc , 0 ) ;
2017-10-18 07:37:45 +03:00
}
/* Symbolic links. */
int
2018-07-19 22:29:11 +03:00
xchk_symlink (
2018-07-19 22:29:12 +03:00
struct xfs_scrub * sc )
2017-10-18 07:37:45 +03:00
{
2018-07-19 22:29:12 +03:00
struct xfs_inode * ip = sc - > ip ;
struct xfs_ifork * ifp ;
loff_t len ;
int error = 0 ;
2017-10-18 07:37:45 +03:00
if ( ! S_ISLNK ( VFS_I ( ip ) - > i_mode ) )
return - ENOENT ;
ifp = XFS_IFORK_PTR ( ip , XFS_DATA_FORK ) ;
2021-03-29 21:11:40 +03:00
len = ip - > i_disk_size ;
2017-10-18 07:37:45 +03:00
/* Plausible size? */
if ( len > XFS_SYMLINK_MAXLEN | | len < = 0 ) {
2018-07-19 22:29:11 +03:00
xchk_fblock_set_corrupt ( sc , XFS_DATA_FORK , 0 ) ;
2017-10-18 07:37:45 +03:00
goto out ;
}
/* Inline symlink? */
2021-04-13 21:15:11 +03:00
if ( ifp - > if_format = = XFS_DINODE_FMT_LOCAL ) {
2017-10-18 07:37:45 +03:00
if ( len > XFS_IFORK_DSIZE ( ip ) | |
len > strnlen ( ifp - > if_u1 . if_data , XFS_IFORK_DSIZE ( ip ) ) )
2018-07-19 22:29:11 +03:00
xchk_fblock_set_corrupt ( sc , XFS_DATA_FORK , 0 ) ;
2017-10-18 07:37:45 +03:00
goto out ;
}
/* Remote symlink; must read the contents. */
error = xfs_readlink_bmap_ilocked ( sc - > ip , sc - > buf ) ;
2018-07-19 22:29:11 +03:00
if ( ! xchk_fblock_process_error ( sc , XFS_DATA_FORK , 0 , & error ) )
2017-10-18 07:37:45 +03:00
goto out ;
if ( strnlen ( sc - > buf , XFS_SYMLINK_MAXLEN ) < len )
2018-07-19 22:29:11 +03:00
xchk_fblock_set_corrupt ( sc , XFS_DATA_FORK , 0 ) ;
2017-10-18 07:37:45 +03:00
out :
return error ;
}