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-acha @ Mon Jul 31 20:08:06 PDT 2023 Lines: 27 32 84.4 %
Date: 2023-07-31 20:08:07 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_trans.h"
      14             : #include "xfs_inode.h"
      15             : #include "xfs_symlink.h"
      16             : #include "xfs_symlink_remote.h"
      17             : #include "scrub/scrub.h"
      18             : #include "scrub/common.h"
      19             : #include "scrub/repair.h"
      20             : 
      21             : /* Set us up to scrub a symbolic link. */
      22             : int
      23    16235094 : xchk_setup_symlink(
      24             :         struct xfs_scrub        *sc)
      25             : {
      26    16235094 :         unsigned int            resblks = 0;
      27    16235094 :         int                     error;
      28             : 
      29             :         /* Allocate the buffer without the inode lock held. */
      30    16235094 :         sc->buf = kvzalloc(XFS_SYMLINK_MAXLEN + 1, XCHK_GFP_FLAGS);
      31    16235066 :         if (!sc->buf)
      32             :                 return -ENOMEM;
      33             : 
      34    32470132 :         if (xchk_could_repair(sc)) {
      35      995970 :                 error = xrep_setup_symlink(sc, &resblks);
      36      995971 :                 if (error)
      37             :                         return error;
      38             :         }
      39             : 
      40    16235067 :         return xchk_setup_inode_contents(sc, resblks);
      41             : }
      42             : 
      43             : /* Symbolic links. */
      44             : 
      45             : int
      46    16155875 : xchk_symlink(
      47             :         struct xfs_scrub        *sc)
      48             : {
      49    16155875 :         struct xfs_inode        *ip = sc->ip;
      50    16155875 :         struct xfs_ifork        *ifp;
      51    16155875 :         loff_t                  len;
      52    16155875 :         int                     error = 0;
      53             : 
      54    16155875 :         if (!S_ISLNK(VFS_I(ip)->i_mode))
      55             :                 return -ENOENT;
      56    16131472 :         ifp = xfs_ifork_ptr(ip, XFS_DATA_FORK);
      57    16131472 :         len = ip->i_disk_size;
      58             : 
      59             :         /* Plausible size? */
      60    16131472 :         if (len > XFS_SYMLINK_MAXLEN || len <= 0) {
      61           0 :                 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
      62           0 :                 goto out;
      63             :         }
      64             : 
      65             :         /* Inline symlink? */
      66    16131472 :         if (ifp->if_format == XFS_DINODE_FMT_LOCAL) {
      67     6232866 :                 if (len > xfs_inode_data_fork_size(ip) ||
      68     3116420 :                     len > strnlen(ifp->if_u1.if_data, xfs_inode_data_fork_size(ip)))
      69           0 :                         xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
      70     3116444 :                 goto out;
      71             :         }
      72             : 
      73             :         /* Remote symlink; must read the contents. */
      74    13015052 :         error = xfs_symlink_remote_read(sc->ip, sc->buf);
      75    13014885 :         if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error))
      76           0 :                 goto out;
      77    26029974 :         if (strnlen(sc->buf, XFS_SYMLINK_MAXLEN) < len)
      78           0 :                 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
      79    13014986 : out:
      80    16131430 :         return error;
      81             : }

Generated by: LCOV version 1.14