The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/openzfs/lib/libspl/os/freebsd/mnttab.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 2006 Pawel Jakub Dawidek <pjd@FreeBSD.org>
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  */
   26 
   27 /*
   28  * This file implements Solaris compatible getmntany() and hasmntopt()
   29  * functions.
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __FBSDID("$FreeBSD$");
   34 
   35 #include <sys/param.h>
   36 #include <sys/mount.h>
   37 #include <sys/mntent.h>
   38 #include <sys/mnttab.h>
   39 
   40 #include <ctype.h>
   41 #include <errno.h>
   42 #include <pthread.h>
   43 #include <stdio.h>
   44 #include <stdlib.h>
   45 #include <string.h>
   46 
   47 static char *
   48 mntopt(char **p)
   49 {
   50         char *cp = *p;
   51         char *retstr;
   52 
   53         while (*cp && isspace(*cp))
   54                 cp++;
   55 
   56         retstr = cp;
   57         while (*cp && *cp != ',')
   58                 cp++;
   59 
   60         if (*cp) {
   61                 *cp = '\0';
   62                 cp++;
   63         }
   64 
   65         *p = cp;
   66         return (retstr);
   67 }
   68 
   69 char *
   70 hasmntopt(struct mnttab *mnt, const char *opt)
   71 {
   72         char tmpopts[MNT_LINE_MAX];
   73         char *f, *opts = tmpopts;
   74 
   75         if (mnt->mnt_mntopts == NULL)
   76                 return (NULL);
   77         (void) strlcpy(opts, mnt->mnt_mntopts, MNT_LINE_MAX);
   78         f = mntopt(&opts);
   79         for (; *f; f = mntopt(&opts)) {
   80                 if (strncmp(opt, f, strlen(opt)) == 0)
   81                         return (f - tmpopts + mnt->mnt_mntopts);
   82         }
   83         return (NULL);
   84 }
   85 
   86 static void
   87 optadd(char *mntopts, size_t size, const char *opt)
   88 {
   89 
   90         if (mntopts[0] != '\0')
   91                 strlcat(mntopts, ",", size);
   92         strlcat(mntopts, opt, size);
   93 }
   94 
   95 static __thread char gfstypename[MFSNAMELEN];
   96 static __thread char gmntfromname[MNAMELEN];
   97 static __thread char gmntonname[MNAMELEN];
   98 static __thread char gmntopts[MNTMAXSTR];
   99 
  100 void
  101 statfs2mnttab(struct statfs *sfs, struct mnttab *mp)
  102 {
  103         long flags;
  104 
  105         strlcpy(gfstypename, sfs->f_fstypename, sizeof (gfstypename));
  106         mp->mnt_fstype = gfstypename;
  107 
  108         strlcpy(gmntfromname, sfs->f_mntfromname, sizeof (gmntfromname));
  109         mp->mnt_special = gmntfromname;
  110 
  111         strlcpy(gmntonname, sfs->f_mntonname, sizeof (gmntonname));
  112         mp->mnt_mountp = gmntonname;
  113 
  114         flags = sfs->f_flags;
  115         gmntopts[0] = '\0';
  116 #define OPTADD(opt)     optadd(gmntopts, sizeof (gmntopts), (opt))
  117         if (flags & MNT_RDONLY)
  118                 OPTADD(MNTOPT_RO);
  119         else
  120                 OPTADD(MNTOPT_RW);
  121         if (flags & MNT_NOSUID)
  122                 OPTADD(MNTOPT_NOSETUID);
  123         else
  124                 OPTADD(MNTOPT_SETUID);
  125         if (flags & MNT_UPDATE)
  126                 OPTADD(MNTOPT_REMOUNT);
  127         if (flags & MNT_NOATIME)
  128                 OPTADD(MNTOPT_NOATIME);
  129         else
  130                 OPTADD(MNTOPT_ATIME);
  131         OPTADD(MNTOPT_NOXATTR);
  132         if (flags & MNT_NOEXEC)
  133                 OPTADD(MNTOPT_NOEXEC);
  134         else
  135                 OPTADD(MNTOPT_EXEC);
  136 #undef  OPTADD
  137         mp->mnt_mntopts = gmntopts;
  138 }
  139 
  140 static pthread_rwlock_t gsfs_lock = PTHREAD_RWLOCK_INITIALIZER;
  141 static struct statfs *gsfs = NULL;
  142 static int allfs = 0;
  143 
  144 static int
  145 statfs_init(void)
  146 {
  147         struct statfs *sfs;
  148         int error;
  149 
  150         (void) pthread_rwlock_wrlock(&gsfs_lock);
  151 
  152         if (gsfs != NULL) {
  153                 free(gsfs);
  154                 gsfs = NULL;
  155         }
  156         allfs = getfsstat(NULL, 0, MNT_NOWAIT);
  157         if (allfs == -1)
  158                 goto fail;
  159         gsfs = malloc(sizeof (gsfs[0]) * allfs * 2);
  160         if (gsfs == NULL)
  161                 goto fail;
  162         allfs = getfsstat(gsfs, (long)(sizeof (gsfs[0]) * allfs * 2),
  163             MNT_NOWAIT);
  164         if (allfs == -1)
  165                 goto fail;
  166         sfs = realloc(gsfs, allfs * sizeof (gsfs[0]));
  167         if (sfs != NULL)
  168                 gsfs = sfs;
  169         (void) pthread_rwlock_unlock(&gsfs_lock);
  170         return (0);
  171 fail:
  172         error = errno;
  173         if (gsfs != NULL)
  174                 free(gsfs);
  175         gsfs = NULL;
  176         allfs = 0;
  177         (void) pthread_rwlock_unlock(&gsfs_lock);
  178         return (error);
  179 }
  180 
  181 int
  182 getmntany(FILE *fd __unused, struct mnttab *mgetp, struct mnttab *mrefp)
  183 {
  184         int i, error;
  185 
  186         error = statfs_init();
  187         if (error != 0)
  188                 return (error);
  189 
  190         (void) pthread_rwlock_rdlock(&gsfs_lock);
  191 
  192         for (i = 0; i < allfs; i++) {
  193                 if (mrefp->mnt_special != NULL &&
  194                     strcmp(mrefp->mnt_special, gsfs[i].f_mntfromname) != 0) {
  195                         continue;
  196                 }
  197                 if (mrefp->mnt_mountp != NULL &&
  198                     strcmp(mrefp->mnt_mountp, gsfs[i].f_mntonname) != 0) {
  199                         continue;
  200                 }
  201                 if (mrefp->mnt_fstype != NULL &&
  202                     strcmp(mrefp->mnt_fstype, gsfs[i].f_fstypename) != 0) {
  203                         continue;
  204                 }
  205                 statfs2mnttab(&gsfs[i], mgetp);
  206                 (void) pthread_rwlock_unlock(&gsfs_lock);
  207                 return (0);
  208         }
  209         (void) pthread_rwlock_unlock(&gsfs_lock);
  210         return (-1);
  211 }
  212 
  213 int
  214 getmntent(FILE *fp, struct mnttab *mp)
  215 {
  216         int error, nfs;
  217 
  218         nfs = (int)lseek(fileno(fp), 0, SEEK_CUR);
  219         if (nfs == -1)
  220                 return (errno);
  221         /* If nfs is 0, we want to refresh out cache. */
  222         if (nfs == 0 || gsfs == NULL) {
  223                 error = statfs_init();
  224                 if (error != 0)
  225                         return (error);
  226         }
  227         (void) pthread_rwlock_rdlock(&gsfs_lock);
  228         if (nfs >= allfs) {
  229                 (void) pthread_rwlock_unlock(&gsfs_lock);
  230                 return (-1);
  231         }
  232         statfs2mnttab(&gsfs[nfs], mp);
  233         (void) pthread_rwlock_unlock(&gsfs_lock);
  234         if (lseek(fileno(fp), 1, SEEK_CUR) == -1)
  235                 return (errno);
  236         return (0);
  237 }

Cache object: a791f49e77e008169b9c267cf18aeef5


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.