LCOV - code coverage report
Current view: top level - fs/quota - quota.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 4 172 2.3 %
Date: 2014-02-18 Functions: 1 19 5.3 %
Branches: 2 156 1.3 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Quota code necessary even when VFS quota support is not compiled
       3                 :            :  * into the kernel.  The interesting stuff is over in dquot.c, here
       4                 :            :  * we have symbols for initial quotactl(2) handling, the sysctl(2)
       5                 :            :  * variables, etc - things needed even when quota support disabled.
       6                 :            :  */
       7                 :            : 
       8                 :            : #include <linux/fs.h>
       9                 :            : #include <linux/namei.h>
      10                 :            : #include <linux/slab.h>
      11                 :            : #include <asm/current.h>
      12                 :            : #include <linux/uaccess.h>
      13                 :            : #include <linux/kernel.h>
      14                 :            : #include <linux/security.h>
      15                 :            : #include <linux/syscalls.h>
      16                 :            : #include <linux/capability.h>
      17                 :            : #include <linux/quotaops.h>
      18                 :            : #include <linux/types.h>
      19                 :            : #include <linux/writeback.h>
      20                 :            : 
      21                 :          0 : static int check_quotactl_permission(struct super_block *sb, int type, int cmd,
      22                 :            :                                      qid_t id)
      23                 :            : {
      24      [ #  #  # ]:          0 :         switch (cmd) {
      25                 :            :         /* these commands do not require any special privilegues */
      26                 :            :         case Q_GETFMT:
      27                 :            :         case Q_SYNC:
      28                 :            :         case Q_GETINFO:
      29                 :            :         case Q_XGETQSTAT:
      30                 :            :         case Q_XGETQSTATV:
      31                 :            :         case Q_XQUOTASYNC:
      32                 :            :                 break;
      33                 :            :         /* allow to query information for dquots we "own" */
      34                 :            :         case Q_GETQUOTA:
      35                 :            :         case Q_XGETQUOTA:
      36 [ #  # ][ #  # ]:          0 :                 if ((type == USRQUOTA && uid_eq(current_euid(), make_kuid(current_user_ns(), id))) ||
                 [ #  # ]
      37         [ #  # ]:          0 :                     (type == GRPQUOTA && in_egroup_p(make_kgid(current_user_ns(), id))))
      38                 :            :                         break;
      39                 :            :                 /*FALLTHROUGH*/
      40                 :            :         default:
      41         [ #  # ]:          0 :                 if (!capable(CAP_SYS_ADMIN))
      42                 :            :                         return -EPERM;
      43                 :            :         }
      44                 :            : 
      45                 :          0 :         return security_quotactl(cmd, type, id, sb);
      46                 :            : }
      47                 :            : 
      48                 :          0 : static void quota_sync_one(struct super_block *sb, void *arg)
      49                 :            : {
      50 [ #  # ][ #  # ]:          0 :         if (sb->s_qcop && sb->s_qcop->quota_sync)
      51                 :          0 :                 sb->s_qcop->quota_sync(sb, *(int *)arg);
      52                 :          0 : }
      53                 :            : 
      54                 :          0 : static int quota_sync_all(int type)
      55                 :            : {
      56                 :            :         int ret;
      57                 :            : 
      58         [ #  # ]:          0 :         if (type >= MAXQUOTAS)
      59                 :            :                 return -EINVAL;
      60                 :          0 :         ret = security_quotactl(Q_SYNC, type, 0, NULL);
      61         [ #  # ]:          0 :         if (!ret)
      62                 :          0 :                 iterate_supers(quota_sync_one, &type);
      63                 :          0 :         return ret;
      64                 :            : }
      65                 :            : 
      66                 :          0 : static int quota_quotaon(struct super_block *sb, int type, int cmd, qid_t id,
      67                 :            :                          struct path *path)
      68                 :            : {
      69 [ #  # ][ #  # ]:          0 :         if (!sb->s_qcop->quota_on && !sb->s_qcop->quota_on_meta)
      70                 :            :                 return -ENOSYS;
      71         [ #  # ]:          0 :         if (sb->s_qcop->quota_on_meta)
      72                 :          0 :                 return sb->s_qcop->quota_on_meta(sb, type, id);
      73         [ #  # ]:          0 :         if (IS_ERR(path))
      74                 :            :                 return PTR_ERR(path);
      75                 :          0 :         return sb->s_qcop->quota_on(sb, type, id, path);
      76                 :            : }
      77                 :            : 
      78                 :          0 : static int quota_getfmt(struct super_block *sb, int type, void __user *addr)
      79                 :            : {
      80                 :            :         __u32 fmt;
      81                 :            : 
      82                 :          0 :         down_read(&sb_dqopt(sb)->dqptr_sem);
      83         [ #  # ]:          0 :         if (!sb_has_quota_active(sb, type)) {
      84                 :          0 :                 up_read(&sb_dqopt(sb)->dqptr_sem);
      85                 :          0 :                 return -ESRCH;
      86                 :            :         }
      87                 :          0 :         fmt = sb_dqopt(sb)->info[type].dqi_format->qf_fmt_id;
      88                 :          0 :         up_read(&sb_dqopt(sb)->dqptr_sem);
      89         [ #  # ]:          0 :         if (copy_to_user(addr, &fmt, sizeof(fmt)))
      90                 :            :                 return -EFAULT;
      91                 :          0 :         return 0;
      92                 :            : }
      93                 :            : 
      94                 :          0 : static int quota_getinfo(struct super_block *sb, int type, void __user *addr)
      95                 :            : {
      96                 :            :         struct if_dqinfo info;
      97                 :            :         int ret;
      98                 :            : 
      99         [ #  # ]:          0 :         if (!sb->s_qcop->get_info)
     100                 :            :                 return -ENOSYS;
     101                 :          0 :         ret = sb->s_qcop->get_info(sb, type, &info);
     102 [ #  # ][ #  # ]:          0 :         if (!ret && copy_to_user(addr, &info, sizeof(info)))
     103                 :            :                 return -EFAULT;
     104                 :          0 :         return ret;
     105                 :            : }
     106                 :            : 
     107                 :          0 : static int quota_setinfo(struct super_block *sb, int type, void __user *addr)
     108                 :            : {
     109                 :            :         struct if_dqinfo info;
     110                 :            : 
     111         [ #  # ]:          0 :         if (copy_from_user(&info, addr, sizeof(info)))
     112                 :            :                 return -EFAULT;
     113         [ #  # ]:          0 :         if (!sb->s_qcop->set_info)
     114                 :            :                 return -ENOSYS;
     115                 :          0 :         return sb->s_qcop->set_info(sb, type, &info);
     116                 :            : }
     117                 :            : 
     118                 :          0 : static void copy_to_if_dqblk(struct if_dqblk *dst, struct fs_disk_quota *src)
     119                 :            : {
     120                 :          0 :         memset(dst, 0, sizeof(*dst));
     121                 :          0 :         dst->dqb_bhardlimit = src->d_blk_hardlimit;
     122                 :          0 :         dst->dqb_bsoftlimit = src->d_blk_softlimit;
     123                 :          0 :         dst->dqb_curspace = src->d_bcount;
     124                 :          0 :         dst->dqb_ihardlimit = src->d_ino_hardlimit;
     125                 :          0 :         dst->dqb_isoftlimit = src->d_ino_softlimit;
     126                 :          0 :         dst->dqb_curinodes = src->d_icount;
     127                 :          0 :         dst->dqb_btime = src->d_btimer;
     128                 :          0 :         dst->dqb_itime = src->d_itimer;
     129                 :          0 :         dst->dqb_valid = QIF_ALL;
     130                 :          0 : }
     131                 :            : 
     132                 :          0 : static int quota_getquota(struct super_block *sb, int type, qid_t id,
     133                 :            :                           void __user *addr)
     134                 :            : {
     135                 :            :         struct kqid qid;
     136                 :            :         struct fs_disk_quota fdq;
     137                 :            :         struct if_dqblk idq;
     138                 :            :         int ret;
     139                 :            : 
     140         [ #  # ]:          0 :         if (!sb->s_qcop->get_dqblk)
     141                 :            :                 return -ENOSYS;
     142                 :          0 :         qid = make_kqid(current_user_ns(), type, id);
     143         [ #  # ]:          0 :         if (!qid_valid(qid))
     144                 :            :                 return -EINVAL;
     145                 :          0 :         ret = sb->s_qcop->get_dqblk(sb, qid, &fdq);
     146         [ #  # ]:          0 :         if (ret)
     147                 :            :                 return ret;
     148                 :          0 :         copy_to_if_dqblk(&idq, &fdq);
     149         [ #  # ]:          0 :         if (copy_to_user(addr, &idq, sizeof(idq)))
     150                 :            :                 return -EFAULT;
     151                 :          0 :         return 0;
     152                 :            : }
     153                 :            : 
     154                 :          0 : static void copy_from_if_dqblk(struct fs_disk_quota *dst, struct if_dqblk *src)
     155                 :            : {
     156                 :          0 :         dst->d_blk_hardlimit = src->dqb_bhardlimit;
     157                 :          0 :         dst->d_blk_softlimit  = src->dqb_bsoftlimit;
     158                 :          0 :         dst->d_bcount = src->dqb_curspace;
     159                 :          0 :         dst->d_ino_hardlimit = src->dqb_ihardlimit;
     160                 :          0 :         dst->d_ino_softlimit = src->dqb_isoftlimit;
     161                 :          0 :         dst->d_icount = src->dqb_curinodes;
     162                 :          0 :         dst->d_btimer = src->dqb_btime;
     163                 :          0 :         dst->d_itimer = src->dqb_itime;
     164                 :            : 
     165                 :          0 :         dst->d_fieldmask = 0;
     166         [ #  # ]:          0 :         if (src->dqb_valid & QIF_BLIMITS)
     167                 :          0 :                 dst->d_fieldmask |= FS_DQ_BSOFT | FS_DQ_BHARD;
     168         [ #  # ]:          0 :         if (src->dqb_valid & QIF_SPACE)
     169                 :          0 :                 dst->d_fieldmask |= FS_DQ_BCOUNT;
     170         [ #  # ]:          0 :         if (src->dqb_valid & QIF_ILIMITS)
     171                 :          0 :                 dst->d_fieldmask |= FS_DQ_ISOFT | FS_DQ_IHARD;
     172         [ #  # ]:          0 :         if (src->dqb_valid & QIF_INODES)
     173                 :          0 :                 dst->d_fieldmask |= FS_DQ_ICOUNT;
     174         [ #  # ]:          0 :         if (src->dqb_valid & QIF_BTIME)
     175                 :          0 :                 dst->d_fieldmask |= FS_DQ_BTIMER;
     176         [ #  # ]:          0 :         if (src->dqb_valid & QIF_ITIME)
     177                 :          0 :                 dst->d_fieldmask |= FS_DQ_ITIMER;
     178                 :          0 : }
     179                 :            : 
     180                 :          0 : static int quota_setquota(struct super_block *sb, int type, qid_t id,
     181                 :            :                           void __user *addr)
     182                 :            : {
     183                 :            :         struct fs_disk_quota fdq;
     184                 :            :         struct if_dqblk idq;
     185                 :            :         struct kqid qid;
     186                 :            : 
     187         [ #  # ]:          0 :         if (copy_from_user(&idq, addr, sizeof(idq)))
     188                 :            :                 return -EFAULT;
     189         [ #  # ]:          0 :         if (!sb->s_qcop->set_dqblk)
     190                 :            :                 return -ENOSYS;
     191                 :          0 :         qid = make_kqid(current_user_ns(), type, id);
     192         [ #  # ]:          0 :         if (!qid_valid(qid))
     193                 :            :                 return -EINVAL;
     194                 :          0 :         copy_from_if_dqblk(&fdq, &idq);
     195                 :          0 :         return sb->s_qcop->set_dqblk(sb, qid, &fdq);
     196                 :            : }
     197                 :            : 
     198                 :          0 : static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr)
     199                 :            : {
     200                 :            :         __u32 flags;
     201                 :            : 
     202         [ #  # ]:          0 :         if (copy_from_user(&flags, addr, sizeof(flags)))
     203                 :            :                 return -EFAULT;
     204         [ #  # ]:          0 :         if (!sb->s_qcop->set_xstate)
     205                 :            :                 return -ENOSYS;
     206                 :          0 :         return sb->s_qcop->set_xstate(sb, flags, cmd);
     207                 :            : }
     208                 :            : 
     209                 :          0 : static int quota_getxstate(struct super_block *sb, void __user *addr)
     210                 :            : {
     211                 :            :         struct fs_quota_stat fqs;
     212                 :            :         int ret;
     213                 :            : 
     214         [ #  # ]:          0 :         if (!sb->s_qcop->get_xstate)
     215                 :            :                 return -ENOSYS;
     216                 :          0 :         ret = sb->s_qcop->get_xstate(sb, &fqs);
     217 [ #  # ][ #  # ]:          0 :         if (!ret && copy_to_user(addr, &fqs, sizeof(fqs)))
     218                 :            :                 return -EFAULT;
     219                 :          0 :         return ret;
     220                 :            : }
     221                 :            : 
     222                 :          0 : static int quota_getxstatev(struct super_block *sb, void __user *addr)
     223                 :            : {
     224                 :            :         struct fs_quota_statv fqs;
     225                 :            :         int ret;
     226                 :            : 
     227         [ #  # ]:          0 :         if (!sb->s_qcop->get_xstatev)
     228                 :            :                 return -ENOSYS;
     229                 :            : 
     230                 :          0 :         memset(&fqs, 0, sizeof(fqs));
     231         [ #  # ]:          0 :         if (copy_from_user(&fqs, addr, 1)) /* Just read qs_version */
     232                 :            :                 return -EFAULT;
     233                 :            : 
     234                 :            :         /* If this kernel doesn't support user specified version, fail */
     235         [ #  # ]:          0 :         switch (fqs.qs_version) {
     236                 :            :         case FS_QSTATV_VERSION1:
     237                 :            :                 break;
     238                 :            :         default:
     239                 :            :                 return -EINVAL;
     240                 :            :         }
     241                 :          0 :         ret = sb->s_qcop->get_xstatev(sb, &fqs);
     242 [ #  # ][ #  # ]:          0 :         if (!ret && copy_to_user(addr, &fqs, sizeof(fqs)))
     243                 :            :                 return -EFAULT;
     244                 :          0 :         return ret;
     245                 :            : }
     246                 :            : 
     247                 :          0 : static int quota_setxquota(struct super_block *sb, int type, qid_t id,
     248                 :            :                            void __user *addr)
     249                 :            : {
     250                 :            :         struct fs_disk_quota fdq;
     251                 :            :         struct kqid qid;
     252                 :            : 
     253         [ #  # ]:          0 :         if (copy_from_user(&fdq, addr, sizeof(fdq)))
     254                 :            :                 return -EFAULT;
     255         [ #  # ]:          0 :         if (!sb->s_qcop->set_dqblk)
     256                 :            :                 return -ENOSYS;
     257                 :          0 :         qid = make_kqid(current_user_ns(), type, id);
     258         [ #  # ]:          0 :         if (!qid_valid(qid))
     259                 :            :                 return -EINVAL;
     260                 :          0 :         return sb->s_qcop->set_dqblk(sb, qid, &fdq);
     261                 :            : }
     262                 :            : 
     263                 :          0 : static int quota_getxquota(struct super_block *sb, int type, qid_t id,
     264                 :            :                            void __user *addr)
     265                 :            : {
     266                 :            :         struct fs_disk_quota fdq;
     267                 :            :         struct kqid qid;
     268                 :            :         int ret;
     269                 :            : 
     270         [ #  # ]:          0 :         if (!sb->s_qcop->get_dqblk)
     271                 :            :                 return -ENOSYS;
     272                 :          0 :         qid = make_kqid(current_user_ns(), type, id);
     273         [ #  # ]:          0 :         if (!qid_valid(qid))
     274                 :            :                 return -EINVAL;
     275                 :          0 :         ret = sb->s_qcop->get_dqblk(sb, qid, &fdq);
     276 [ #  # ][ #  # ]:          0 :         if (!ret && copy_to_user(addr, &fdq, sizeof(fdq)))
     277                 :            :                 return -EFAULT;
     278                 :          0 :         return ret;
     279                 :            : }
     280                 :            : 
     281                 :            : /* Copy parameters and call proper function */
     282                 :          0 : static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
     283                 :            :                        void __user *addr, struct path *path)
     284                 :            : {
     285                 :            :         int ret;
     286                 :            : 
     287 [ #  # ][ #  # ]:          0 :         if (type >= (XQM_COMMAND(cmd) ? XQM_MAXQUOTAS : MAXQUOTAS))
     288                 :            :                 return -EINVAL;
     289         [ #  # ]:          0 :         if (!sb->s_qcop)
     290                 :            :                 return -ENOSYS;
     291                 :            : 
     292                 :          0 :         ret = check_quotactl_permission(sb, type, cmd, id);
     293         [ #  # ]:          0 :         if (ret < 0)
     294                 :            :                 return ret;
     295                 :            : 
     296   [ #  #  #  #  :          0 :         switch (cmd) {
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     297                 :            :         case Q_QUOTAON:
     298                 :          0 :                 return quota_quotaon(sb, type, cmd, id, path);
     299                 :            :         case Q_QUOTAOFF:
     300         [ #  # ]:          0 :                 if (!sb->s_qcop->quota_off)
     301                 :            :                         return -ENOSYS;
     302                 :          0 :                 return sb->s_qcop->quota_off(sb, type);
     303                 :            :         case Q_GETFMT:
     304                 :          0 :                 return quota_getfmt(sb, type, addr);
     305                 :            :         case Q_GETINFO:
     306                 :          0 :                 return quota_getinfo(sb, type, addr);
     307                 :            :         case Q_SETINFO:
     308                 :          0 :                 return quota_setinfo(sb, type, addr);
     309                 :            :         case Q_GETQUOTA:
     310                 :          0 :                 return quota_getquota(sb, type, id, addr);
     311                 :            :         case Q_SETQUOTA:
     312                 :          0 :                 return quota_setquota(sb, type, id, addr);
     313                 :            :         case Q_SYNC:
     314         [ #  # ]:          0 :                 if (!sb->s_qcop->quota_sync)
     315                 :            :                         return -ENOSYS;
     316                 :          0 :                 return sb->s_qcop->quota_sync(sb, type);
     317                 :            :         case Q_XQUOTAON:
     318                 :            :         case Q_XQUOTAOFF:
     319                 :            :         case Q_XQUOTARM:
     320                 :          0 :                 return quota_setxstate(sb, cmd, addr);
     321                 :            :         case Q_XGETQSTAT:
     322                 :          0 :                 return quota_getxstate(sb, addr);
     323                 :            :         case Q_XGETQSTATV:
     324                 :          0 :                 return quota_getxstatev(sb, addr);
     325                 :            :         case Q_XSETQLIM:
     326                 :          0 :                 return quota_setxquota(sb, type, id, addr);
     327                 :            :         case Q_XGETQUOTA:
     328                 :          0 :                 return quota_getxquota(sb, type, id, addr);
     329                 :            :         case Q_XQUOTASYNC:
     330         [ #  # ]:          0 :                 if (sb->s_flags & MS_RDONLY)
     331                 :            :                         return -EROFS;
     332                 :            :                 /* XFS quotas are fully coherent now, making this call a noop */
     333                 :          0 :                 return 0;
     334                 :            :         default:
     335                 :            :                 return -EINVAL;
     336                 :            :         }
     337                 :            : }
     338                 :            : 
     339                 :            : #ifdef CONFIG_BLOCK
     340                 :            : 
     341                 :            : /* Return 1 if 'cmd' will block on frozen filesystem */
     342                 :            : static int quotactl_cmd_write(int cmd)
     343                 :            : {
     344         [ #  # ]:          0 :         switch (cmd) {
     345                 :            :         case Q_GETFMT:
     346                 :            :         case Q_GETINFO:
     347                 :            :         case Q_SYNC:
     348                 :            :         case Q_XGETQSTAT:
     349                 :            :         case Q_XGETQSTATV:
     350                 :            :         case Q_XGETQUOTA:
     351                 :            :         case Q_XQUOTASYNC:
     352                 :            :                 return 0;
     353                 :            :         }
     354                 :            :         return 1;
     355                 :            : }
     356                 :            : 
     357                 :            : #endif /* CONFIG_BLOCK */
     358                 :            : 
     359                 :            : /*
     360                 :            :  * look up a superblock on which quota ops will be performed
     361                 :            :  * - use the name of a block device to find the superblock thereon
     362                 :            :  */
     363                 :          0 : static struct super_block *quotactl_block(const char __user *special, int cmd)
     364                 :            : {
     365                 :            : #ifdef CONFIG_BLOCK
     366                 :            :         struct block_device *bdev;
     367                 :            :         struct super_block *sb;
     368                 :          0 :         struct filename *tmp = getname(special);
     369                 :            : 
     370         [ #  # ]:          0 :         if (IS_ERR(tmp))
     371                 :            :                 return ERR_CAST(tmp);
     372                 :          0 :         bdev = lookup_bdev(tmp->name);
     373                 :          0 :         putname(tmp);
     374         [ #  # ]:          0 :         if (IS_ERR(bdev))
     375                 :            :                 return ERR_CAST(bdev);
     376         [ #  # ]:          0 :         if (quotactl_cmd_write(cmd))
     377                 :          0 :                 sb = get_super_thawed(bdev);
     378                 :            :         else
     379                 :          0 :                 sb = get_super(bdev);
     380                 :          0 :         bdput(bdev);
     381         [ #  # ]:          0 :         if (!sb)
     382                 :            :                 return ERR_PTR(-ENODEV);
     383                 :            : 
     384                 :          0 :         return sb;
     385                 :            : #else
     386                 :            :         return ERR_PTR(-ENODEV);
     387                 :            : #endif
     388                 :            : }
     389                 :            : 
     390                 :            : /*
     391                 :            :  * This is the system call interface. This communicates with
     392                 :            :  * the user-level programs. Currently this only supports diskquota
     393                 :            :  * calls. Maybe we need to add the process quotas etc. in the future,
     394                 :            :  * but we probably should use rlimits for that.
     395                 :            :  */
     396                 :          0 : SYSCALL_DEFINE4(quotactl, unsigned int, cmd, const char __user *, special,
     397                 :            :                 qid_t, id, void __user *, addr)
     398                 :            : {
     399                 :            :         uint cmds, type;
     400                 :            :         struct super_block *sb = NULL;
     401                 :            :         struct path path, *pathp = NULL;
     402                 :            :         int ret;
     403                 :            : 
     404                 :          1 :         cmds = cmd >> SUBCMDSHIFT;
     405                 :          1 :         type = cmd & SUBCMDMASK;
     406                 :            : 
     407                 :            :         /*
     408                 :            :          * As a special case Q_SYNC can be called without a specific device.
     409                 :            :          * It will iterate all superblocks that have quota enabled and call
     410                 :            :          * the sync action on each of them.
     411                 :            :          */
     412         [ +  - ]:          1 :         if (!special) {
     413         [ -  + ]:          1 :                 if (cmds == Q_SYNC)
     414                 :          0 :                         return quota_sync_all(type);
     415                 :            :                 return -ENODEV;
     416                 :            :         }
     417                 :            : 
     418                 :            :         /*
     419                 :            :          * Path for quotaon has to be resolved before grabbing superblock
     420                 :            :          * because that gets s_umount sem which is also possibly needed by path
     421                 :            :          * resolution (think about autofs) and thus deadlocks could arise.
     422                 :            :          */
     423         [ #  # ]:          0 :         if (cmds == Q_QUOTAON) {
     424                 :          0 :                 ret = user_path_at(AT_FDCWD, addr, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &path);
     425         [ #  # ]:          0 :                 if (ret)
     426                 :            :                         pathp = ERR_PTR(ret);
     427                 :            :                 else
     428                 :            :                         pathp = &path;
     429                 :            :         }
     430                 :            : 
     431                 :          0 :         sb = quotactl_block(special, cmds);
     432         [ #  # ]:          0 :         if (IS_ERR(sb)) {
     433                 :            :                 ret = PTR_ERR(sb);
     434                 :            :                 goto out;
     435                 :            :         }
     436                 :            : 
     437                 :          0 :         ret = do_quotactl(sb, type, cmds, id, addr, pathp);
     438                 :            : 
     439                 :          0 :         drop_super(sb);
     440                 :            : out:
     441 [ #  # ][ #  # ]:          0 :         if (pathp && !IS_ERR(pathp))
     442                 :          0 :                 path_put(pathp);
     443                 :            :         return ret;
     444                 :            : }

Generated by: LCOV version 1.9