LCOV - code coverage report
Current view: top level - fs/xfs/scrub - symlink.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc3-djwx @ Mon Jul 31 20:08:22 PDT 2023 Lines: 22 27 81.5 %
Date: 2023-07-31 20:08:22 Functions: 2 2 100.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0-or-later
       2             : /*
       3             :  * Copyright (C) 2017-2023 Oracle.  All Rights Reserved.
       4             :  * Author: Darrick J. Wong <djwong@kernel.org>
       5             :  */
       6             : #include "xfs.h"
       7             : #include "xfs_fs.h"
       8             : #include "xfs_shared.h"
       9             : #include "xfs_format.h"
      10             : #include "xfs_trans_resv.h"
      11             : #include "xfs_mount.h"
      12             : #include "xfs_log_format.h"
      13             : #include "xfs_inode.h"
      14             : #include "xfs_symlink.h"
      15             : #include "scrub/scrub.h"
      16             : #include "scrub/common.h"
      17             : 
      18             : /* Set us up to scrub a symbolic link. */
      19             : int
      20    41809375 : xchk_setup_symlink(
      21             :         struct xfs_scrub        *sc)
      22             : {
      23             :         /* Allocate the buffer without the inode lock held. */
      24    41809375 :         sc->buf = kvzalloc(XFS_SYMLINK_MAXLEN + 1, XCHK_GFP_FLAGS);
      25    41816830 :         if (!sc->buf)
      26             :                 return -ENOMEM;
      27             : 
      28    41816830 :         return xchk_setup_inode_contents(sc, 0);
      29             : }
      30             : 
      31             : /* Symbolic links. */
      32             : 
      33             : int
      34    41598289 : xchk_symlink(
      35             :         struct xfs_scrub        *sc)
      36             : {
      37    41598289 :         struct xfs_inode        *ip = sc->ip;
      38    41598289 :         struct xfs_ifork        *ifp;
      39    41598289 :         loff_t                  len;
      40    41598289 :         int                     error = 0;
      41             : 
      42    41598289 :         if (!S_ISLNK(VFS_I(ip)->i_mode))
      43             :                 return -ENOENT;
      44    41444553 :         ifp = xfs_ifork_ptr(ip, XFS_DATA_FORK);
      45    41444553 :         len = ip->i_disk_size;
      46             : 
      47             :         /* Plausible size? */
      48    41444553 :         if (len > XFS_SYMLINK_MAXLEN || len <= 0) {
      49           0 :                 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
      50           0 :                 goto out;
      51             :         }
      52             : 
      53             :         /* Inline symlink? */
      54    41444553 :         if (ifp->if_format == XFS_DINODE_FMT_LOCAL) {
      55    28116645 :                 if (len > xfs_inode_data_fork_size(ip) ||
      56    14057581 :                     len > strnlen(ifp->if_u1.if_data, xfs_inode_data_fork_size(ip)))
      57           0 :                         xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
      58    14059056 :                 goto out;
      59             :         }
      60             : 
      61             :         /* Remote symlink; must read the contents. */
      62    27386972 :         error = xfs_readlink_bmap_ilocked(sc->ip, sc->buf);
      63    27387237 :         if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error))
      64           0 :                 goto out;
      65    54772447 :         if (strnlen(sc->buf, XFS_SYMLINK_MAXLEN) < len)
      66           0 :                 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
      67    27393433 : out:
      68    41452489 :         return error;
      69             : }

Generated by: LCOV version 1.14