LCOV - code coverage report
Current view: top level - fs/xfs/scrub - symlink.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc4-xfsx @ Mon Jul 31 20:08:34 PDT 2023 Lines: 27 32 84.4 %
Date: 2023-07-31 20:08:34 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    14059112 : xchk_setup_symlink(
      24             :         struct xfs_scrub        *sc)
      25             : {
      26    14059112 :         unsigned int            resblks = 0;
      27    14059112 :         int                     error;
      28             : 
      29             :         /* Allocate the buffer without the inode lock held. */
      30    14059112 :         sc->buf = kvzalloc(XFS_SYMLINK_MAXLEN + 1, XCHK_GFP_FLAGS);
      31    14061353 :         if (!sc->buf)
      32             :                 return -ENOMEM;
      33             : 
      34    28122706 :         if (xchk_could_repair(sc)) {
      35      144580 :                 error = xrep_setup_symlink(sc, &resblks);
      36      144691 :                 if (error)
      37             :                         return error;
      38             :         }
      39             : 
      40    14061464 :         return xchk_setup_inode_contents(sc, resblks);
      41             : }
      42             : 
      43             : /* Symbolic links. */
      44             : 
      45             : int
      46    13954433 : xchk_symlink(
      47             :         struct xfs_scrub        *sc)
      48             : {
      49    13954433 :         struct xfs_inode        *ip = sc->ip;
      50    13954433 :         struct xfs_ifork        *ifp;
      51    13954433 :         loff_t                  len;
      52    13954433 :         int                     error = 0;
      53             : 
      54    13954433 :         if (!S_ISLNK(VFS_I(ip)->i_mode))
      55             :                 return -ENOENT;
      56    13925735 :         ifp = xfs_ifork_ptr(ip, XFS_DATA_FORK);
      57    13925735 :         len = ip->i_disk_size;
      58             : 
      59             :         /* Plausible size? */
      60    13925735 :         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    13925735 :         if (ifp->if_format == XFS_DINODE_FMT_LOCAL) {
      67     6891187 :                 if (len > xfs_inode_data_fork_size(ip) ||
      68     3445279 :                     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     3445793 :                 goto out;
      71             :         }
      72             : 
      73             :         /* Remote symlink; must read the contents. */
      74    10480456 :         error = xfs_symlink_remote_read(sc->ip, sc->buf);
      75    10479933 :         if (!xchk_fblock_process_error(sc, XFS_DATA_FORK, 0, &error))
      76           0 :                 goto out;
      77    20962191 :         if (strnlen(sc->buf, XFS_SYMLINK_MAXLEN) < len)
      78           0 :                 xchk_fblock_set_corrupt(sc, XFS_DATA_FORK, 0);
      79    10484158 : out:
      80    13929951 :         return error;
      81             : }

Generated by: LCOV version 1.14