root/compat/freebsd/freebsd_file.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. convert_from_freebsd_mount_type
  2. freebsd_sys_mount
  3. freebsd_sys_open
  4. compat_43_freebsd_sys_creat
  5. freebsd_sys_link
  6. freebsd_sys_unlink
  7. freebsd_sys_chdir
  8. freebsd_sys_mknod
  9. freebsd_sys_chmod
  10. freebsd_sys_chown
  11. freebsd_sys_unmount
  12. freebsd_sys_access
  13. freebsd_sys_chflags
  14. compat_43_freebsd_sys_stat
  15. compat_43_freebsd_sys_lstat
  16. freebsd_sys_revoke
  17. freebsd_sys_symlink
  18. freebsd_sys_readlink
  19. freebsd_sys_execve
  20. freebsd_sys_chroot
  21. freebsd_sys_rename
  22. compat_43_freebsd_sys_truncate
  23. freebsd_sys_mkfifo
  24. freebsd_sys_mkdir
  25. freebsd_sys_rmdir
  26. statfs_to_freebsd_statfs
  27. freebsd_sys_statfs
  28. freebsd_sys_fstatfs
  29. freebsd_sys_getfsstat
  30. freebsd_sys_getfh
  31. freebsd_sys_stat
  32. freebsd_sys_lstat
  33. freebsd_sys_pathconf
  34. freebsd_sys_truncate
  35. freebsd_sys_fcntl

    1 /*      $OpenBSD: freebsd_file.c,v 1.25 2006/06/25 15:01:53 sturm Exp $ */
    2 /*      $NetBSD: freebsd_file.c,v 1.3 1996/05/03 17:03:09 christos Exp $        */
    3 
    4 /*
    5  * Copyright (c) 1995 Frank van der Linden
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. All advertising materials mentioning features or use of this software
   17  *    must display the following acknowledgement:
   18  *      This product includes software developed for the NetBSD Project
   19  *      by Frank van der Linden
   20  * 4. The name of the author may not be used to endorse or promote products
   21  *    derived from this software without specific prior written permission
   22  *
   23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   26  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   28  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   32  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   33  *
   34  *      from: linux_file.c,v 1.3 1995/04/04 04:21:30 mycroft Exp
   35  */
   36 
   37 #include <sys/param.h>
   38 #include <sys/systm.h>
   39 #include <sys/namei.h>
   40 #include <sys/proc.h>
   41 #include <sys/file.h>
   42 #include <sys/stat.h>
   43 #include <sys/filedesc.h>
   44 #include <sys/ioctl.h>
   45 #include <sys/kernel.h>
   46 #include <sys/vnode.h>
   47 #include <sys/mount.h>
   48 #include <sys/malloc.h>
   49 
   50 #include <sys/syscallargs.h>
   51 
   52 #include <compat/freebsd/freebsd_signal.h>
   53 #include <compat/freebsd/freebsd_syscallargs.h>
   54 #include <compat/freebsd/freebsd_util.h>
   55 
   56 #define ARRAY_LENGTH(array)     (sizeof(array)/sizeof(array[0]))
   57 
   58 const char freebsd_emul_path[] = "/emul/freebsd";
   59 
   60 static char * convert_from_freebsd_mount_type(int);
   61 void statfs_to_freebsd_statfs(struct proc *, struct mount *, struct statfs *, struct freebsd_statfs *);
   62 
   63 struct freebsd_statfs {
   64         long    f_spare2;               /* placeholder */
   65         long    f_bsize;                /* fundamental file system block size */
   66         long    f_iosize;               /* optimal transfer block size */
   67         long    f_blocks;               /* total data blocks in file system */
   68         long    f_bfree;                /* free blocks in fs */
   69         long    f_bavail;               /* free blocks avail to non-superuser */
   70         long    f_files;                /* total file nodes in file system */
   71         long    f_ffree;                /* free file nodes in fs */
   72         fsid_t  f_fsid;                 /* file system id */
   73         uid_t   f_owner;                /* user that mounted the filesystem */
   74         int     f_type;                 /* type of filesystem */
   75         int     f_flags;                /* copy of mount exported flags */
   76         long    f_syncwrites;           /* count of sync writes since mount */
   77         long    f_asyncwrites;          /* count of async writes since mount */
   78         char    f_fstypename[MFSNAMELEN]; /* fs type name */
   79         char    f_mntonname[MNAMELEN];  /* directory on which mounted */
   80         char    f_mntfromname[MNAMELEN];/* mounted filesystem */
   81 };
   82 
   83 static char *
   84 convert_from_freebsd_mount_type(type)
   85         int type;
   86 {
   87         static char *freebsd_mount_type[] = {
   88                 NULL,     /*  0 = MOUNT_NONE */
   89                 "ffs",    /*  1 = "Fast" Filesystem */
   90                 "nfs",    /*  2 = Network Filesystem */
   91                 "mfs",    /*  3 = Memory Filesystem */
   92                 "msdos",  /*  4 = MSDOS Filesystem */
   93                 "lfs",    /*  5 = Log-based Filesystem */
   94                 "lofs",   /*  6 = Loopback filesystem */
   95                 "fdesc",  /*  7 = File Descriptor Filesystem */
   96                 "portal", /*  8 = Portal Filesystem */
   97                 "null",   /*  9 = Minimal Filesystem Layer */
   98                 "umap",   /* 10 = User/Group Identifier Remapping Filesystem */
   99                 "kernfs", /* 11 = Kernel Information Filesystem */
  100                 "procfs", /* 12 = /proc Filesystem */
  101                 "afs",    /* 13 = Andrew Filesystem */
  102                 "cd9660", /* 14 = ISO9660 (aka CDROM) Filesystem */
  103                 "union",  /* 15 = Union (translucent) Filesystem */
  104                 NULL,     /* 16 = "devfs" - existing device Filesystem */
  105 #if 0 /* These filesystems don't exist in FreeBSD */
  106                 "adosfs", /* ?? = AmigaDOS Filesystem */
  107 #endif
  108         };
  109 
  110         if (type < 0 || type >= ARRAY_LENGTH(freebsd_mount_type))
  111                 return (NULL);
  112         return (freebsd_mount_type[type]);
  113 }
  114 
  115 int
  116 freebsd_sys_mount(p, v, retval)
  117         struct proc *p;
  118         void *v;
  119         register_t *retval;
  120 {
  121         struct freebsd_sys_mount_args /* {
  122                 syscallarg(int) type;
  123                 syscallarg(char *) path;
  124                 syscallarg(int) flags;
  125                 syscallarg(caddr_t) data;
  126         } */ *uap = v;
  127         int error;
  128         char *type, *s;
  129         caddr_t sg = stackgap_init(p->p_emul);
  130         struct sys_mount_args bma;
  131 
  132         if ((type = convert_from_freebsd_mount_type(SCARG(uap, type))) == NULL)
  133                 return ENODEV;
  134         s = stackgap_alloc(&sg, MFSNAMELEN + 1);
  135         if ((error = copyout(type, s, strlen(type) + 1)) != 0)
  136                 return error;
  137         SCARG(&bma, type) = s;
  138         FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  139         SCARG(&bma, path) = SCARG(uap, path);
  140         SCARG(&bma, flags) = SCARG(uap, flags);
  141         SCARG(&bma, data) = SCARG(uap, data);
  142         return sys_mount(p, &bma, retval);
  143 }
  144 
  145 /*
  146  * The following syscalls are only here because of the alternate path check.
  147  */
  148 
  149 /* XXX - UNIX domain: int freebsd_sys_bind(int s, caddr_t name, int namelen); */
  150 /* XXX - UNIX domain: int freebsd_sys_connect(int s, caddr_t name, int namelen); */
  151 
  152 
  153 int
  154 freebsd_sys_open(p, v, retval)
  155         struct proc *p;
  156         void *v;
  157         register_t *retval;
  158 {
  159         struct freebsd_sys_open_args /* {
  160                 syscallarg(char *) path;
  161                 syscallarg(int) flags;
  162                 syscallarg(int) mode;
  163         } */ *uap = v;
  164         caddr_t sg = stackgap_init(p->p_emul);
  165 
  166         if (SCARG(uap, flags) & O_CREAT)
  167                 FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
  168         else
  169                 FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  170         return sys_open(p, uap, retval);
  171 }
  172 
  173 int
  174 compat_43_freebsd_sys_creat(p, v, retval)
  175         struct proc *p;
  176         void *v;
  177         register_t *retval;
  178 {
  179         struct compat_43_freebsd_sys_creat_args /* {
  180                 syscallarg(char *) path;
  181                 syscallarg(int) mode;
  182         } */ *uap = v;
  183         caddr_t sg  = stackgap_init(p->p_emul);
  184 
  185         FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
  186         return compat_43_sys_creat(p, uap, retval);
  187 }
  188 
  189 int
  190 freebsd_sys_link(p, v, retval)
  191         struct proc *p;
  192         void *v;
  193         register_t *retval;
  194 {
  195         struct freebsd_sys_link_args /* {
  196                 syscallarg(char *) path;
  197                 syscallarg(char *) link;
  198         } */ *uap = v;
  199         caddr_t sg = stackgap_init(p->p_emul);
  200 
  201         FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  202         FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, link));
  203         return sys_link(p, uap, retval);
  204 }
  205 
  206 int
  207 freebsd_sys_unlink(p, v, retval)
  208         struct proc *p;
  209         void *v;
  210         register_t *retval;
  211 {
  212         struct freebsd_sys_unlink_args /* {
  213                 syscallarg(char *) path;
  214         } */ *uap = v;
  215         caddr_t sg = stackgap_init(p->p_emul);
  216 
  217         FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  218         return sys_unlink(p, uap, retval);
  219 }
  220 
  221 int
  222 freebsd_sys_chdir(p, v, retval)
  223         struct proc *p;
  224         void *v;
  225         register_t *retval;
  226 {
  227         struct freebsd_sys_chdir_args /* {
  228                 syscallarg(char *) path;
  229         } */ *uap = v;
  230         caddr_t sg = stackgap_init(p->p_emul);
  231 
  232         FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  233         return sys_chdir(p, uap, retval);
  234 }
  235 
  236 int
  237 freebsd_sys_mknod(p, v, retval)
  238         struct proc *p;
  239         void *v;
  240         register_t *retval;
  241 {
  242         struct freebsd_sys_mknod_args /* {
  243                 syscallarg(char *) path;
  244                 syscallarg(int) mode;
  245                 syscallarg(int) dev;
  246         } */ *uap = v;
  247         caddr_t sg = stackgap_init(p->p_emul);
  248 
  249         FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
  250         return sys_mknod(p, uap, retval);
  251 }
  252 
  253 int
  254 freebsd_sys_chmod(p, v, retval)
  255         struct proc *p;
  256         void *v;
  257         register_t *retval;
  258 {
  259         struct freebsd_sys_chmod_args /* {
  260                 syscallarg(char *) path;
  261                 syscallarg(int) mode;
  262         } */ *uap = v;
  263         caddr_t sg = stackgap_init(p->p_emul);
  264 
  265         FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  266         return sys_chmod(p, uap, retval);
  267 }
  268 
  269 int
  270 freebsd_sys_chown(p, v, retval)
  271         struct proc *p;
  272         void *v;
  273         register_t *retval;
  274 {
  275         struct freebsd_sys_chown_args /* {
  276                 syscallarg(char *) path;
  277                 syscallarg(int) uid;
  278                 syscallarg(int) gid;
  279         } */ *uap = v;
  280         caddr_t sg = stackgap_init(p->p_emul);
  281 
  282         FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  283         return sys_chown(p, uap, retval);
  284 }
  285 
  286 int
  287 freebsd_sys_unmount(p, v, retval)
  288         struct proc *p;
  289         void *v;
  290         register_t *retval;
  291 {
  292         struct freebsd_sys_unmount_args /* {
  293                 syscallarg(char *) path;
  294                 syscallarg(int) flags;
  295         } */ *uap = v;
  296         caddr_t sg = stackgap_init(p->p_emul);
  297 
  298         FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  299         return sys_unmount(p, uap, retval);
  300 }
  301 
  302 int
  303 freebsd_sys_access(p, v, retval)
  304         struct proc *p;
  305         void *v;
  306         register_t *retval;
  307 {
  308         struct freebsd_sys_access_args /* {
  309                 syscallarg(char *) path;
  310                 syscallarg(int) flags;
  311         } */ *uap = v;
  312         caddr_t sg = stackgap_init(p->p_emul);
  313 
  314         FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  315         return sys_access(p, uap, retval);
  316 }
  317 
  318 int
  319 freebsd_sys_chflags(p, v, retval)
  320         struct proc *p;
  321         void *v;
  322         register_t *retval;
  323 {
  324         struct freebsd_sys_chflags_args /* {
  325                 syscallarg(char *) path;
  326                 syscallarg(int) flags;
  327         } */ *uap = v;
  328         caddr_t sg = stackgap_init(p->p_emul);
  329 
  330         FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  331         return sys_chflags(p, uap, retval);
  332 }
  333 
  334 int
  335 compat_43_freebsd_sys_stat(p, v, retval)
  336         struct proc *p;
  337         void *v;
  338         register_t *retval;
  339 {
  340         struct compat_43_freebsd_sys_stat_args /* {
  341                 syscallarg(char *) path;
  342                 syscallarg(struct stat43 *) ub;
  343         } */ *uap = v;
  344         caddr_t sg = stackgap_init(p->p_emul);
  345 
  346         FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  347         return compat_43_sys_stat(p, uap, retval);
  348 }
  349 
  350 int
  351 compat_43_freebsd_sys_lstat(p, v, retval)
  352         struct proc *p;
  353         void *v;
  354         register_t *retval;
  355 {
  356         struct compat_43_freebsd_sys_lstat_args /* {
  357                 syscallarg(char *) path;
  358                 syscallarg(struct stat43 *) ub;
  359         } */ *uap = v;
  360         caddr_t sg = stackgap_init(p->p_emul);
  361 
  362         FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  363         return compat_43_sys_lstat(p, uap, retval);
  364 }
  365 
  366 int
  367 freebsd_sys_revoke(p, v, retval)
  368         struct proc *p;
  369         void *v;
  370         register_t *retval;
  371 {
  372         struct freebsd_sys_revoke_args /* {
  373                 syscallarg(char *) path;
  374         } */ *uap = v;
  375         caddr_t sg = stackgap_init(p->p_emul);
  376 
  377         FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  378         return sys_revoke(p, uap, retval);
  379 }
  380 
  381 int
  382 freebsd_sys_symlink(p, v, retval)
  383         struct proc *p;
  384         void *v;
  385         register_t *retval;
  386 {
  387         struct freebsd_sys_symlink_args /* {
  388                 syscallarg(char *) path;
  389                 syscallarg(char *) link;
  390         } */ *uap = v;
  391         caddr_t sg = stackgap_init(p->p_emul);
  392 
  393         FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  394         FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, link));
  395         return sys_symlink(p, uap, retval);
  396 }
  397 
  398 int
  399 freebsd_sys_readlink(p, v, retval)
  400         struct proc *p;
  401         void *v;
  402         register_t *retval;
  403 {
  404         struct freebsd_sys_readlink_args /* {
  405                 syscallarg(char *) path;
  406                 syscallarg(char *) buf;
  407                 syscallarg(int) count;
  408         } */ *uap = v;
  409         caddr_t sg = stackgap_init(p->p_emul);
  410 
  411         FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  412         return sys_readlink(p, uap, retval);
  413 }
  414 
  415 int
  416 freebsd_sys_execve(p, v, retval)
  417         struct proc *p;
  418         void *v;
  419         register_t *retval;
  420 {
  421         struct freebsd_sys_execve_args /* {
  422                 syscallarg(char *) path;
  423                 syscallarg(char **) argp;
  424                 syscallarg(char **) envp;
  425         } */ *uap = v;
  426         struct sys_execve_args ap;
  427         caddr_t sg;
  428 
  429         sg = stackgap_init(p->p_emul);
  430         FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  431 
  432         SCARG(&ap, path) = SCARG(uap, path);
  433         SCARG(&ap, argp) = SCARG(uap, argp);
  434         SCARG(&ap, envp) = SCARG(uap, envp);
  435 
  436         return sys_execve(p, &ap, retval);
  437 }
  438 
  439 int
  440 freebsd_sys_chroot(p, v, retval)
  441         struct proc *p;
  442         void *v;
  443         register_t *retval;
  444 {
  445         struct freebsd_sys_chroot_args /* {
  446                 syscallarg(char *) path;
  447         } */ *uap = v;
  448         caddr_t sg = stackgap_init(p->p_emul);
  449 
  450         FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  451         return sys_chroot(p, uap, retval);
  452 }
  453 
  454 int
  455 freebsd_sys_rename(p, v, retval)
  456         struct proc *p;
  457         void *v;
  458         register_t *retval;
  459 {
  460         struct freebsd_sys_rename_args /* {
  461                 syscallarg(char *) from;
  462                 syscallarg(char *) to;
  463         } */ *uap = v;
  464         caddr_t sg = stackgap_init(p->p_emul);
  465 
  466         FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, from));
  467         FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, to));
  468         return sys_rename(p, uap, retval);
  469 }
  470 
  471 int
  472 compat_43_freebsd_sys_truncate(p, v, retval)
  473         struct proc *p;
  474         void *v;
  475         register_t *retval;
  476 {
  477         struct compat_43_freebsd_sys_truncate_args /* {
  478                 syscallarg(char *) path;
  479                 syscallarg(long) length;
  480         } */ *uap = v;
  481         caddr_t sg = stackgap_init(p->p_emul);
  482 
  483         FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  484         return compat_43_sys_truncate(p, uap, retval);
  485 }
  486 
  487 int
  488 freebsd_sys_mkfifo(p, v, retval)
  489         struct proc *p;
  490         void *v;
  491         register_t *retval;
  492 {
  493         struct freebsd_sys_mkfifo_args /* {
  494                 syscallarg(char *) path;
  495                 syscallarg(int) mode;
  496         } */ *uap = v;
  497         caddr_t sg = stackgap_init(p->p_emul);
  498 
  499         FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
  500         return sys_mkfifo(p, uap, retval);
  501 }
  502 
  503 int
  504 freebsd_sys_mkdir(p, v, retval)
  505         struct proc *p;
  506         void *v;
  507         register_t *retval;
  508 {
  509         struct freebsd_sys_mkdir_args /* {
  510                 syscallarg(char *) path;
  511                 syscallarg(int) mode;
  512         } */ *uap = v;
  513         caddr_t sg = stackgap_init(p->p_emul);
  514 
  515         FREEBSD_CHECK_ALT_CREAT(p, &sg, SCARG(uap, path));
  516         return sys_mkdir(p, uap, retval);
  517 }
  518 
  519 int
  520 freebsd_sys_rmdir(p, v, retval)
  521         struct proc *p;
  522         void *v;
  523         register_t *retval;
  524 {
  525         struct freebsd_sys_rmdir_args /* {
  526                 syscallarg(char *) path;
  527         } */ *uap = v;
  528         caddr_t sg = stackgap_init(p->p_emul);
  529 
  530         FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  531         return sys_rmdir(p, uap, retval);
  532 }
  533 
  534 /*
  535  * Convert struct statfs -> struct freebsd_statfs
  536  */
  537 void
  538 statfs_to_freebsd_statfs(p, mp, sp, fsp)
  539         struct proc *p;
  540         struct mount *mp;
  541         struct statfs *sp;
  542         struct freebsd_statfs *fsp;
  543 {
  544         fsp->f_bsize = sp->f_bsize;
  545         fsp->f_iosize = sp->f_iosize;
  546         fsp->f_blocks = sp->f_blocks;
  547         fsp->f_bfree = sp->f_bfree;
  548         fsp->f_bavail = sp->f_bavail;
  549         fsp->f_files = sp->f_files;
  550         fsp->f_ffree = sp->f_ffree;
  551         /* Don't let non-root see filesystem id (for NFS security) */
  552         if (suser(p, 0))
  553                 fsp->f_fsid.val[0] = fsp->f_fsid.val[1] = 0;
  554         else
  555                 bcopy(&sp->f_fsid, &fsp->f_fsid, sizeof(fsp->f_fsid));
  556         fsp->f_owner = sp->f_owner;
  557         fsp->f_type = mp->mnt_vfc->vfc_typenum;
  558         fsp->f_flags = sp->f_flags;
  559         fsp->f_syncwrites = sp->f_syncwrites;
  560         fsp->f_asyncwrites = sp->f_asyncwrites;
  561         bcopy(sp->f_fstypename, fsp->f_fstypename, MFSNAMELEN);
  562         bcopy(sp->f_mntonname, fsp->f_mntonname, MNAMELEN);
  563         bcopy(sp->f_mntfromname, fsp->f_mntfromname, MNAMELEN);
  564 }
  565 
  566 /*
  567  * Get filesystem statistics.
  568  */
  569 /* ARGSUSED */
  570 int
  571 freebsd_sys_statfs(p, v, retval)
  572         struct proc *p;
  573         void *v;
  574         register_t *retval;
  575 {
  576         register struct freebsd_sys_statfs_args /* {
  577                 syscallarg(char *) path;
  578                 syscallarg(struct freebsd_statfs *) buf;
  579         } */ *uap = v;
  580         register struct mount *mp;
  581         register struct statfs *sp;
  582         struct freebsd_statfs fsb;
  583         int error;
  584         struct nameidata nd;
  585         caddr_t sg = stackgap_init(p->p_emul);
  586 
  587         FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  588         NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);
  589         if ((error = namei(&nd)) != 0)
  590                 return (error);
  591         mp = nd.ni_vp->v_mount;
  592         sp = &mp->mnt_stat;
  593         vrele(nd.ni_vp);
  594         if ((error = VFS_STATFS(mp, sp, p)) != 0)
  595                 return (error);
  596         sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
  597 
  598         statfs_to_freebsd_statfs(p, mp, sp, &fsb);
  599         return (copyout((caddr_t)&fsb, (caddr_t)SCARG(uap, buf), sizeof(fsb)));
  600 }
  601 
  602 /*
  603  * Get filesystem statistics.
  604  */
  605 /* ARGSUSED */
  606 int
  607 freebsd_sys_fstatfs(p, v, retval)
  608         struct proc *p;
  609         void *v;
  610         register_t *retval;
  611 {
  612         register struct freebsd_sys_fstatfs_args /* {
  613                 syscallarg(int) fd;
  614                 syscallarg(struct freebsd_statfs *) buf;
  615         } */ *uap = v;
  616         struct file *fp;
  617         struct mount *mp;
  618         register struct statfs *sp;
  619         struct freebsd_statfs fsb;
  620         int error;
  621 
  622         if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)
  623                 return (error);
  624         mp = ((struct vnode *)fp->f_data)->v_mount;
  625         sp = &mp->mnt_stat;
  626         error = VFS_STATFS(mp, sp, p);
  627         FRELE(fp);
  628         if (error)
  629                 return (error);
  630         sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
  631 
  632         statfs_to_freebsd_statfs(p, mp, sp, &fsb);
  633         return (copyout((caddr_t)&fsb, (caddr_t)SCARG(uap, buf), sizeof(fsb)));
  634 }
  635 
  636 /*
  637  * Get statistics on all filesystems.
  638  */
  639 int
  640 freebsd_sys_getfsstat(p, v, retval)
  641         struct proc *p;
  642         void *v;
  643         register_t *retval;
  644 {
  645         register struct freebsd_sys_getfsstat_args /* {
  646                 syscallarg(struct freebsd_statfs *) buf;
  647                 syscallarg(long) bufsize;
  648                 syscallarg(int) flags;
  649         } */ *uap = v;
  650         register struct mount *mp, *nmp;
  651         register struct statfs *sp;
  652         struct freebsd_statfs fsb;
  653         caddr_t sfsp;
  654         long count, maxcount;
  655         int error, flags = SCARG(uap, flags);
  656 
  657         maxcount = SCARG(uap, bufsize) / sizeof(struct freebsd_statfs);
  658         sfsp = (caddr_t)SCARG(uap, buf);
  659         count = 0;
  660 
  661         for (mp = CIRCLEQ_FIRST(&mountlist); mp != CIRCLEQ_END(&mountlist);
  662             mp = nmp) {
  663                 if (vfs_busy(mp, VB_READ|VB_NOWAIT)) {
  664                         nmp = CIRCLEQ_NEXT(mp, mnt_list);
  665                         continue;
  666                 }
  667                 if (sfsp && count < maxcount) {
  668                         sp = &mp->mnt_stat;
  669 
  670                         /* Refresh stats unless MNT_NOWAIT is specified */
  671                         if (flags != MNT_NOWAIT &&
  672                             flags != MNT_LAZY &&
  673                             (flags == MNT_WAIT ||
  674                              flags == 0) &&
  675                             (error = VFS_STATFS(mp, sp, p))) {
  676                                 nmp = CIRCLEQ_NEXT(mp, mnt_list);
  677                                 vfs_unbusy(mp);
  678                                 continue;
  679                         }
  680                         sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
  681 
  682                         statfs_to_freebsd_statfs(p, mp, sp, &fsb);
  683                         error = copyout((caddr_t)&fsb, sfsp, sizeof(fsb));
  684                         if (error) {
  685                                 vfs_unbusy(mp);
  686                                 return (error);
  687                         }
  688                         sfsp += sizeof(fsb);
  689                 }
  690                 count++;
  691                 nmp = CIRCLEQ_NEXT(mp, mnt_list);
  692                 vfs_unbusy(mp);
  693         }
  694 
  695         if (sfsp && count > maxcount)
  696                 *retval = maxcount;
  697         else
  698                 *retval = count;
  699 
  700         return (0);
  701 }
  702 
  703 #ifdef NFSCLIENT
  704 int
  705 freebsd_sys_getfh(p, v, retval)
  706         struct proc *p;
  707         void *v;
  708         register_t *retval;
  709 {
  710         struct freebsd_sys_getfh_args /* {
  711                 syscallarg(char *) fname;
  712                 syscallarg(fhandle_t *) fhp;
  713         } */ *uap = v;
  714         caddr_t sg = stackgap_init(p->p_emul);
  715 
  716         FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, fname));
  717         return sys_getfh(p, uap, retval);
  718 }
  719 #endif /* NFSCLIENT */
  720 
  721 int
  722 freebsd_sys_stat(p, v, retval)
  723         struct proc *p;
  724         void *v;
  725         register_t *retval;
  726 {
  727         struct freebsd_sys_stat_args /* {
  728                 syscallarg(char *) path;
  729                 syscallarg(struct stat35 *) ub;
  730         } */ *uap = v;
  731         caddr_t sg = stackgap_init(p->p_emul);
  732 
  733         FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  734         return compat_35_sys_stat(p, uap, retval);
  735 }
  736 
  737 int
  738 freebsd_sys_lstat(p, v, retval)
  739         struct proc *p;
  740         void *v;
  741         register_t *retval;
  742 {
  743         struct freebsd_sys_lstat_args /* {
  744                 syscallarg(char *) path;
  745                 syscallarg(struct stat35 *) ub;
  746         } */ *uap = v;
  747         caddr_t sg = stackgap_init(p->p_emul);
  748 
  749         FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  750         return compat_35_sys_lstat(p, uap, retval);
  751 }
  752 
  753 int
  754 freebsd_sys_pathconf(p, v, retval)
  755         struct proc *p;
  756         void *v;
  757         register_t *retval;
  758 {
  759         struct freebsd_sys_pathconf_args /* {
  760                 syscallarg(char *) path;
  761                 syscallarg(int) name;
  762         } */ *uap = v;
  763         caddr_t sg = stackgap_init(p->p_emul);
  764 
  765         FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  766         return sys_pathconf(p, uap, retval);
  767 }
  768 
  769 int
  770 freebsd_sys_truncate(p, v, retval)
  771         struct proc *p;
  772         void *v;
  773         register_t *retval;
  774 {
  775         struct freebsd_sys_truncate_args /* {
  776                 syscallarg(char *) path;
  777                 syscallarg(int) pad;
  778                 syscallarg(off_t) length;
  779         } */ *uap = v;
  780         caddr_t sg = stackgap_init(p->p_emul);
  781 
  782         FREEBSD_CHECK_ALT_EXIST(p, &sg, SCARG(uap, path));
  783         return sys_truncate(p, uap, retval);
  784 }
  785 
  786 /*
  787  * Just pass on everything to our fcntl, except for F_[GS]ETOWN on pipes,
  788  * where we translate to SIOC[GS]PGRP.
  789  */
  790 int
  791 freebsd_sys_fcntl(p, v, retval)
  792         struct proc *p;
  793         void *v;
  794         register_t *retval;
  795 {
  796         struct freebsd_sys_fcntl_args /* {
  797                 syscallarg(int) fd;
  798                 syscallarg(int) cmd;
  799                 syscallarg(void *) arg;
  800         } */ *uap = v;
  801         int fd, cmd, error;
  802         struct filedesc *fdp;
  803         struct file *fp;
  804 
  805         fd = SCARG(uap, fd);
  806         cmd = SCARG(uap, cmd);
  807 
  808         switch (cmd) {
  809         case F_GETOWN:
  810         case F_SETOWN:
  811                 /* Our pipes does not understand F_[GS]ETOWN.  */ 
  812                 fdp = p->p_fd;
  813                 if ((fp = fd_getfile(fdp, fd)) == NULL)
  814                         return (EBADF);
  815                 if (fp->f_type == DTYPE_PIPE) {
  816                         FREF(fp);
  817                         error = (*fp->f_ops->fo_ioctl)(fp,
  818                             cmd == F_GETOWN ? SIOCGPGRP : SIOCSPGRP,
  819                             (caddr_t)&SCARG(uap, arg), p);
  820                         FRELE(fp);
  821                         return (error);
  822                 }
  823                 break;
  824         }
  825 
  826         return (sys_fcntl(p, uap, retval));
  827 }
  828 

/* [<][>][^][v][top][bottom][index][help] */