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/kern/vfs_xattr.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 /*      $NetBSD: vfs_xattr.c,v 1.9 2006/11/01 10:17:59 yamt Exp $       */
    2 
    3 /*-
    4  * Copyright (c) 2005 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Jason R. Thorpe.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *      This product includes software developed by the NetBSD
   21  *      Foundation, Inc. and its contributors.
   22  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23  *    contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 /*
   40  * Copyright (c) 1989, 1993
   41  *      The Regents of the University of California.  All rights reserved.
   42  * (c) UNIX System Laboratories, Inc.
   43  * All or some portions of this file are derived from material licensed
   44  * to the University of California by American Telephone and Telegraph
   45  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
   46  * the permission of UNIX System Laboratories, Inc.
   47  *
   48  * Redistribution and use in source and binary forms, with or without
   49  * modification, are permitted provided that the following conditions
   50  * are met:
   51  * 1. Redistributions of source code must retain the above copyright
   52  *    notice, this list of conditions and the following disclaimer.
   53  * 2. Redistributions in binary form must reproduce the above copyright
   54  *    notice, this list of conditions and the following disclaimer in the
   55  *    documentation and/or other materials provided with the distribution.
   56  * 3. Neither the name of the University nor the names of its contributors
   57  *    may be used to endorse or promote products derived from this software
   58  *    without specific prior written permission.
   59  *
   60  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   61  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   62  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   63  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   64  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   65  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   66  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   67  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   68  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   69  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   70  * SUCH DAMAGE.
   71  */
   72 
   73 /*
   74  * VFS extended attribute support.
   75  */
   76 
   77 #include <sys/cdefs.h>
   78 __KERNEL_RCSID(0, "$NetBSD: vfs_xattr.c,v 1.9 2006/11/01 10:17:59 yamt Exp $");
   79 
   80 #include <sys/param.h>
   81 #include <sys/systm.h>
   82 #include <sys/namei.h>
   83 #include <sys/filedesc.h>
   84 #include <sys/kernel.h>
   85 #include <sys/file.h>
   86 #include <sys/vnode.h>
   87 #include <sys/mount.h>
   88 #include <sys/proc.h>
   89 #include <sys/uio.h>
   90 #include <sys/extattr.h>
   91 #include <sys/xattr.h>
   92 #include <sys/sysctl.h>
   93 #include <sys/sa.h>
   94 #include <sys/syscallargs.h>
   95 #include <sys/kauth.h>
   96 
   97 /*
   98  * Credential check based on process requesting service, and per-attribute
   99  * permissions.
  100  *
  101  * NOTE: Vnode must be locked.
  102  */
  103 int
  104 extattr_check_cred(struct vnode *vp, int attrnamespace,
  105     kauth_cred_t cred, struct lwp *l, int access)
  106 {
  107 
  108         if (cred == NOCRED)
  109                 return (0);
  110 
  111         switch (attrnamespace) {
  112         case EXTATTR_NAMESPACE_SYSTEM:
  113                 /*
  114                  * Do we really want to allow this, or just require that
  115                  * these requests come from kernel code (NOCRED case above)?
  116                  */
  117                 return (kauth_authorize_generic(cred, KAUTH_GENERIC_ISSUSER,
  118                     &l->l_acflag));
  119 
  120         case EXTATTR_NAMESPACE_USER:
  121                 return (VOP_ACCESS(vp, access, cred, l));
  122 
  123         default:
  124                 return (EPERM);
  125         }
  126 }
  127 
  128 /*
  129  * Default vfs_extattrctl routine for file systems that do not support
  130  * it.
  131  */
  132 /*ARGSUSED*/
  133 int
  134 vfs_stdextattrctl(struct mount *mp, int cmt, struct vnode *vp,
  135     int attrnamespace, const char *attrname, struct lwp *l)
  136 {
  137 
  138         if (vp != NULL)
  139                 VOP_UNLOCK(vp, 0);
  140         return (EOPNOTSUPP);
  141 }
  142 
  143 /*
  144  * Push extended attribute configuration information into the file
  145  * system.
  146  *
  147  * NOTE: Not all file systems that support extended attributes will
  148  * require the use of this system call.
  149  */
  150 int
  151 sys_extattrctl(struct lwp *l, void *v, register_t *retval)
  152 {
  153         struct sys_extattrctl_args /* {
  154                 syscallarg(const char *) path;
  155                 syscallarg(int) cmd;
  156                 syscallarg(const char *) filename;
  157                 syscallarg(int) attrnamespace;
  158                 syscallarg(const char *) attrname;
  159         } */ *uap = v;
  160         struct vnode *vp;
  161         struct nameidata nd;
  162         struct mount *mp;
  163         char attrname[EXTATTR_MAXNAMELEN];
  164         int error;
  165 
  166         if (SCARG(uap, attrname) != NULL) {
  167                 error = copyinstr(SCARG(uap, attrname), attrname,
  168                     sizeof(attrname), NULL);
  169                 if (error)
  170                         return (error);
  171         }
  172 
  173         vp = NULL;
  174         if (SCARG(uap, filename) != NULL) {
  175                 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,
  176                     SCARG(uap, filename), l);
  177                 error = namei(&nd);
  178                 if (error)
  179                         return (error);
  180                 vp = nd.ni_vp;
  181         }
  182 
  183         NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), l);
  184         error = namei(&nd);
  185         if (error) {
  186                 if (vp != NULL)
  187                         vput(vp);
  188                 return (error);
  189         }
  190 
  191         error = vn_start_write(nd.ni_vp, &mp, V_WAIT | V_PCATCH);
  192         if (error) {
  193                 if (vp != NULL)
  194                         vput(vp);
  195                 return (error);
  196         }
  197 
  198         error = VFS_EXTATTRCTL(mp, SCARG(uap, cmd), vp,
  199             SCARG(uap, attrnamespace),
  200             SCARG(uap, attrname) != NULL ? attrname : NULL, l);
  201 
  202         vn_finished_write(mp, 0);
  203 
  204         if (vp != NULL)
  205                 vrele(vp);
  206 
  207         return (error);
  208 }
  209 
  210 /*****************************************************************************
  211  * Internal routines to manipulate file system extended attributes:
  212  *      - set
  213  *      - get
  214  *      - delete
  215  *      - list
  216  *****************************************************************************/
  217 
  218 /*
  219  * extattr_set_vp:
  220  *
  221  *      Set a named extended attribute on a file or directory.
  222  */
  223 static int
  224 extattr_set_vp(struct vnode *vp, int attrnamespace, const char *attrname,
  225     const void *data, size_t nbytes, struct lwp *l, register_t *retval)
  226 {
  227         struct mount *mp;
  228         struct uio auio;
  229         struct iovec aiov;
  230         ssize_t cnt;
  231         int error;
  232 
  233         error = vn_start_write(vp, &mp, V_WAIT | V_PCATCH);
  234         if (error)
  235                 return (error);
  236         VOP_LEASE(vp, l, l->l_cred, LEASE_WRITE);
  237         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
  238 
  239         aiov.iov_base = __UNCONST(data);        /* XXXUNCONST kills const */
  240         aiov.iov_len = nbytes;
  241         auio.uio_iov = &aiov;
  242         auio.uio_iovcnt = 1;
  243         auio.uio_offset = 0;
  244         if (nbytes > INT_MAX) {
  245                 error = EINVAL;
  246                 goto done;
  247         }
  248         auio.uio_resid = nbytes;
  249         auio.uio_rw = UIO_WRITE;
  250         KASSERT(l == curlwp);
  251         auio.uio_vmspace = l->l_proc->p_vmspace;
  252         cnt = nbytes;
  253 
  254         error = VOP_SETEXTATTR(vp, attrnamespace, attrname, &auio,
  255             l->l_cred, l);
  256         cnt -= auio.uio_resid;
  257         retval[0] = cnt;
  258 
  259  done:
  260         VOP_UNLOCK(vp, 0);
  261         vn_finished_write(mp, 0);
  262         return (error);
  263 }
  264 
  265 /*
  266  * extattr_get_vp:
  267  *
  268  *      Get a named extended attribute on a file or directory.
  269  */
  270 static int
  271 extattr_get_vp(struct vnode *vp, int attrnamespace, const char *attrname,
  272     void *data, size_t nbytes, struct lwp *l, register_t *retval)
  273 {
  274         struct uio auio, *auiop;
  275         struct iovec aiov;
  276         ssize_t cnt;
  277         size_t size, *sizep;
  278         int error;
  279 
  280         VOP_LEASE(vp, l, l->l_cred, LEASE_READ);
  281         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
  282 
  283         /*
  284          * Slightly unusual semantics: if the user provides a NULL data
  285          * pointer, they don't want to receive the data, just the maximum
  286          * read length.
  287          */
  288         auiop = NULL;
  289         sizep = NULL;
  290         cnt = 0;
  291         if (data != NULL) {
  292                 aiov.iov_base = data;
  293                 aiov.iov_len = nbytes;
  294                 auio.uio_iov = &aiov;
  295                 auio.uio_offset = 0;
  296                 if (nbytes > INT_MAX) {
  297                         error = EINVAL;
  298                         goto done;
  299                 }
  300                 auio.uio_resid = nbytes;
  301                 auio.uio_rw = UIO_READ;
  302                 KASSERT(l == curlwp);
  303                 auio.uio_vmspace = l->l_proc->p_vmspace;
  304                 auiop = &auio;
  305                 cnt = nbytes;
  306         } else
  307                 sizep = &size;
  308 
  309         error = VOP_GETEXTATTR(vp, attrnamespace, attrname, auiop, sizep,
  310             l->l_cred, l);
  311 
  312         if (auiop != NULL) {
  313                 cnt -= auio.uio_resid;
  314                 retval[0] = cnt;
  315         } else
  316                 retval[0] = size;
  317 
  318  done:
  319         VOP_UNLOCK(vp, 0);
  320         return (error);
  321 }
  322 
  323 /*
  324  * extattr_delete_vp:
  325  *
  326  *      Delete a named extended attribute on a file or directory.
  327  */
  328 static int
  329 extattr_delete_vp(struct vnode *vp, int attrnamespace, const char *attrname,
  330     struct lwp *l)
  331 {
  332         struct mount *mp;
  333         int error;
  334 
  335         error = vn_start_write(vp, &mp, V_WAIT | V_PCATCH);
  336         if (error)
  337                 return (error);
  338         VOP_LEASE(vp, l, l->l_cred, LEASE_WRITE);
  339         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
  340 
  341         error = VOP_DELETEEXTATTR(vp, attrnamespace, attrname, l->l_cred, l);
  342         if (error == EOPNOTSUPP)
  343                 error = VOP_SETEXTATTR(vp, attrnamespace, attrname, NULL,
  344                     l->l_cred, l);
  345 
  346         VOP_UNLOCK(vp, 0);
  347         vn_finished_write(mp, 0);
  348         return (error);
  349 }
  350 
  351 /*
  352  * extattr_list_vp:
  353  *
  354  *      Retrieve a list of extended attributes on a file or directory.
  355  */
  356 static int
  357 extattr_list_vp(struct vnode *vp, int attrnamespace, void *data, size_t nbytes,
  358     struct lwp *l, register_t *retval)
  359 {
  360         struct uio auio, *auiop;
  361         size_t size, *sizep;
  362         struct iovec aiov;
  363         ssize_t cnt;
  364         int error;
  365 
  366         VOP_LEASE(vp, l, l->l_cred, LEASE_READ);
  367         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
  368 
  369         auiop = NULL;
  370         sizep = NULL;
  371         cnt = 0;
  372         if (data != NULL) {
  373                 aiov.iov_base = data;
  374                 aiov.iov_len = nbytes;
  375                 auio.uio_iov = &aiov;
  376                 auio.uio_offset = 0;
  377                 if (nbytes > INT_MAX) {
  378                         error = EINVAL;
  379                         goto done;
  380                 }
  381                 auio.uio_resid = nbytes;
  382                 auio.uio_rw = UIO_READ;
  383                 KASSERT(l == curlwp);
  384                 auio.uio_vmspace = l->l_proc->p_vmspace;
  385                 auiop = &auio;
  386                 cnt = nbytes;
  387         } else
  388                 sizep = &size;
  389 
  390         error = VOP_LISTEXTATTR(vp, attrnamespace, auiop, sizep,
  391             l->l_cred, l);
  392 
  393         if (auiop != NULL) {
  394                 cnt -= auio.uio_resid;
  395                 retval[0] = cnt;
  396         } else
  397                 retval[0] = size;
  398 
  399  done:
  400         VOP_UNLOCK(vp, 0);
  401         return (error);
  402 }
  403 
  404 /*****************************************************************************
  405  * BSD <sys/extattr.h> API for file system extended attributes
  406  *****************************************************************************/
  407 
  408 int
  409 sys_extattr_set_fd(struct lwp *l, void *v, register_t *retval)
  410 {
  411         struct sys_extattr_set_fd_args /* {
  412                 syscallarg(int) fd;
  413                 syscallarg(int) attrnamespace;
  414                 syscallarg(const char *) attrname;
  415                 syscallarg(const void *) data;
  416                 syscallarg(size_t) nbytes;
  417         } */ *uap = v;
  418         struct file *fp;
  419         struct vnode *vp;
  420         char attrname[EXTATTR_MAXNAMELEN];
  421         int error;
  422 
  423         error = copyinstr(SCARG(uap, attrname), attrname, sizeof(attrname),
  424             NULL);
  425         if (error)
  426                 return (error);
  427 
  428         error = getvnode(l->l_proc->p_fd, SCARG(uap, fd), &fp);
  429         if (error)
  430                 return (error);
  431         vp = (struct vnode *) fp->f_data;
  432 
  433         error = extattr_set_vp(vp, SCARG(uap, attrnamespace), attrname,
  434             SCARG(uap, data), SCARG(uap, nbytes), l, retval);
  435 
  436         FILE_UNUSE(fp, l);
  437         return (error);
  438 }
  439 
  440 int
  441 sys_extattr_set_file(struct lwp *l, void *v, register_t *retval)
  442 {
  443         struct sys_extattr_set_file_args /* {
  444                 syscallarg(const char *) path;
  445                 syscallarg(int) attrnamespace;
  446                 syscallarg(const char *) attrname;
  447                 syscallarg(const void *) data;
  448                 syscallarg(size_t) nbytes;
  449         } */ *uap = v;
  450         struct nameidata nd;
  451         char attrname[EXTATTR_MAXNAMELEN];
  452         int error;
  453 
  454         error = copyinstr(SCARG(uap, attrname), attrname, sizeof(attrname),
  455             NULL);
  456         if (error)
  457                 return (error);
  458 
  459         NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), l);
  460         error = namei(&nd);
  461         if (error)
  462                 return (error);
  463 
  464         error = extattr_set_vp(nd.ni_vp, SCARG(uap, attrnamespace), attrname,
  465             SCARG(uap, data), SCARG(uap, nbytes), l, retval);
  466 
  467         vrele(nd.ni_vp);
  468         return (error);
  469 }
  470 
  471 int
  472 sys_extattr_set_link(struct lwp *l, void *v, register_t *retval)
  473 {
  474         struct sys_extattr_set_link_args /* {
  475                 syscallarg(const char *) path;
  476                 syscallarg(int) attrnamespace;
  477                 syscallarg(const char *) attrname;
  478                 syscallarg(const void *) data;
  479                 syscallarg(size_t) nbytes;
  480         } */ *uap = v;
  481         struct nameidata nd;
  482         char attrname[EXTATTR_MAXNAMELEN];
  483         int error;
  484 
  485         error = copyinstr(SCARG(uap, attrname), attrname, sizeof(attrname),
  486             NULL);
  487         if (error)
  488                 return (error);
  489 
  490         NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), l);
  491         error = namei(&nd);
  492         if (error)
  493                 return (error);
  494 
  495         error = extattr_set_vp(nd.ni_vp, SCARG(uap, attrnamespace), attrname,
  496             SCARG(uap, data), SCARG(uap, nbytes), l, retval);
  497 
  498         vrele(nd.ni_vp);
  499         return (error);
  500 }
  501 
  502 int
  503 sys_extattr_get_fd(struct lwp *l, void *v, register_t *retval)
  504 {
  505         struct sys_extattr_get_fd_args /* {
  506                 syscallarg(int) fd;
  507                 syscallarg(int) attrnamespace;
  508                 syscallarg(const char *) attrname;
  509                 syscallarg(void *) data;
  510                 syscallarg(size_t) nbytes;
  511         } */ *uap = v;
  512         struct file *fp;
  513         struct vnode *vp;
  514         char attrname[EXTATTR_MAXNAMELEN];
  515         int error;
  516 
  517         error = copyinstr(SCARG(uap, attrname), attrname, sizeof(attrname),
  518             NULL);
  519         if (error)
  520                 return (error);
  521 
  522         error = getvnode(l->l_proc->p_fd, SCARG(uap, fd), &fp);
  523         if (error)
  524                 return (error);
  525         vp = (struct vnode *) fp->f_data;
  526 
  527         error = extattr_get_vp(vp, SCARG(uap, attrnamespace), attrname,
  528             SCARG(uap, data), SCARG(uap, nbytes), l, retval);
  529 
  530         FILE_UNUSE(fp, l);
  531         return (error);
  532 }
  533 
  534 int
  535 sys_extattr_get_file(struct lwp *l, void *v, register_t *retval)
  536 {
  537         struct sys_extattr_get_file_args /* {
  538                 syscallarg(const char *) path;
  539                 syscallarg(int) attrnamespace;
  540                 syscallarg(const char *) attrname;
  541                 syscallarg(void *) data;
  542                 syscallarg(size_t) nbytes;
  543         } */ *uap = v;
  544         struct nameidata nd;
  545         char attrname[EXTATTR_MAXNAMELEN];
  546         int error;
  547 
  548         error = copyinstr(SCARG(uap, attrname), attrname, sizeof(attrname),
  549             NULL);
  550         if (error)
  551                 return (error);
  552 
  553         NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), l);
  554         error = namei(&nd);
  555         if (error)
  556                 return (error);
  557 
  558         error = extattr_get_vp(nd.ni_vp, SCARG(uap, attrnamespace), attrname,
  559             SCARG(uap, data), SCARG(uap, nbytes), l, retval);
  560 
  561         vrele(nd.ni_vp);
  562         return (error);
  563 }
  564 
  565 int
  566 sys_extattr_get_link(struct lwp *l, void *v, register_t *retval)
  567 {
  568         struct sys_extattr_get_link_args /* {
  569                 syscallarg(const char *) path;
  570                 syscallarg(int) attrnamespace;
  571                 syscallarg(const char *) attrname;
  572                 syscallarg(void *) data;
  573                 syscallarg(size_t) nbytes;
  574         } */ *uap = v;
  575         struct nameidata nd;
  576         char attrname[EXTATTR_MAXNAMELEN];
  577         int error;
  578 
  579         error = copyinstr(SCARG(uap, attrname), attrname, sizeof(attrname),
  580             NULL);
  581         if (error)
  582                 return (error);
  583 
  584         NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), l);
  585         error = namei(&nd);
  586         if (error)
  587                 return (error);
  588 
  589         error = extattr_get_vp(nd.ni_vp, SCARG(uap, attrnamespace), attrname,
  590             SCARG(uap, data), SCARG(uap, nbytes), l, retval);
  591 
  592         vrele(nd.ni_vp);
  593         return (error);
  594 }
  595 
  596 int
  597 sys_extattr_delete_fd(struct lwp *l, void *v, register_t *retval)
  598 {
  599         struct sys_extattr_delete_fd_args /* {
  600                 syscallarg(int) fd;
  601                 syscallarg(int) attrnamespace;
  602                 syscallarg(const char *) attrname;
  603         } */ *uap = v;
  604         struct file *fp;
  605         struct vnode *vp;
  606         char attrname[EXTATTR_MAXNAMELEN];
  607         int error;
  608 
  609         error = copyinstr(SCARG(uap, attrname), attrname, sizeof(attrname),
  610             NULL);
  611         if (error)
  612                 return (error);
  613 
  614         error = getvnode(l->l_proc->p_fd, SCARG(uap, fd), &fp);
  615         if (error)
  616                 return (error);
  617         vp = (struct vnode *) fp->f_data;
  618 
  619         error = extattr_delete_vp(vp, SCARG(uap, attrnamespace), attrname, l);
  620 
  621         FILE_UNUSE(fp, l);
  622         return (error);
  623 }
  624 
  625 int
  626 sys_extattr_delete_file(struct lwp *l, void *v, register_t *retval)
  627 {
  628         struct sys_extattr_delete_file_args /* {
  629                 syscallarg(const char *) path;
  630                 syscallarg(int) attrnamespace;
  631                 syscallarg(const char *) attrname;
  632         } */ *uap = v;
  633         struct nameidata nd;
  634         char attrname[EXTATTR_MAXNAMELEN];
  635         int error;
  636 
  637         error = copyinstr(SCARG(uap, attrname), attrname, sizeof(attrname),
  638             NULL);
  639         if (error)
  640                 return (error);
  641 
  642         NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), l);
  643         error = namei(&nd);
  644         if (error)
  645                 return (error);
  646 
  647         error = extattr_delete_vp(nd.ni_vp, SCARG(uap, attrnamespace), attrname,
  648             l);
  649 
  650         vrele(nd.ni_vp);
  651         return (error);
  652 }
  653 
  654 int
  655 sys_extattr_delete_link(struct lwp *l, void *v, register_t *retval)
  656 {
  657         struct sys_extattr_delete_link_args /* {
  658                 syscallarg(const char *) path;
  659                 syscallarg(int) attrnamespace;
  660                 syscallarg(const char *) attrname;
  661         } */ *uap = v;
  662         struct nameidata nd;
  663         char attrname[EXTATTR_MAXNAMELEN];
  664         int error;
  665 
  666         error = copyinstr(SCARG(uap, attrname), attrname, sizeof(attrname),
  667             NULL);
  668         if (error)
  669                 return (error);
  670 
  671         NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), l);
  672         error = namei(&nd);
  673         if (error)
  674                 return (error);
  675 
  676         error = extattr_delete_vp(nd.ni_vp, SCARG(uap, attrnamespace), attrname,
  677             l);
  678 
  679         vrele(nd.ni_vp);
  680         return (error);
  681 }
  682 
  683 int
  684 sys_extattr_list_fd(struct lwp *l, void *v, register_t *retval)
  685 {
  686         struct sys_extattr_list_fd_args /* {
  687                 syscallarg(int) fd;
  688                 syscallarg(int) attrnamespace;
  689                 syscallarg(void *) data;
  690                 syscallarg(size_t) nbytes;
  691         } */ *uap = v;
  692         struct file *fp;
  693         struct vnode *vp;
  694         int error;
  695 
  696         error = getvnode(l->l_proc->p_fd, SCARG(uap, fd), &fp);
  697         if (error)
  698                 return (error);
  699         vp = (struct vnode *) fp->f_data;
  700 
  701         error = extattr_list_vp(vp, SCARG(uap, attrnamespace),
  702             SCARG(uap, data), SCARG(uap, nbytes), l, retval);
  703 
  704         FILE_UNUSE(fp, l);
  705         return (error);
  706 }
  707 
  708 int
  709 sys_extattr_list_file(struct lwp *l, void *v, register_t *retval)
  710 {
  711         struct sys_extattr_list_file_args /* {
  712                 syscallarg(const char *) path;
  713                 syscallarg(int) attrnamespace;
  714                 syscallarg(void *) data;
  715                 syscallarg(size_t) nbytes;
  716         } */ *uap = v;
  717         struct nameidata nd;
  718         int error;
  719 
  720         NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), l);
  721         error = namei(&nd);
  722         if (error)
  723                 return (error);
  724 
  725         error = extattr_list_vp(nd.ni_vp, SCARG(uap, attrnamespace),
  726             SCARG(uap, data), SCARG(uap, nbytes), l, retval);
  727 
  728         vrele(nd.ni_vp);
  729         return (error);
  730 }
  731 
  732 int
  733 sys_extattr_list_link(struct lwp *l, void *v, register_t *retval)
  734 {
  735         struct sys_extattr_list_link_args /* {
  736                 syscallarg(const char *) path;
  737                 syscallarg(int) attrnamespace;
  738                 syscallarg(void *) data;
  739                 syscallarg(size_t) nbytes;
  740         } */ *uap = v;
  741         struct nameidata nd;
  742         int error;
  743 
  744         NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), l);
  745         error = namei(&nd);
  746         if (error)
  747                 return (error);
  748 
  749         error = extattr_list_vp(nd.ni_vp, SCARG(uap, attrnamespace),
  750             SCARG(uap, data), SCARG(uap, nbytes), l, retval);
  751 
  752         vrele(nd.ni_vp);
  753         return (error);
  754 }
  755 
  756 /*****************************************************************************
  757  * Linux-compatible <sys/xattr.h> API for file system extended attributes
  758  *****************************************************************************/
  759 
  760 int
  761 sys_setxattr(struct lwp *l, void *v, register_t *retval)
  762 {
  763         struct sys_setxattr_args /* {
  764                 syscallarg(const char *) path;
  765                 syscallarg(const char *) name;
  766                 syscallarg(void *) value;
  767                 syscallarg(size_t) size;
  768                 syscallarg(int) flags;
  769         } */ *uap = v;
  770         struct nameidata nd;
  771         char attrname[XATTR_NAME_MAX];
  772         int error;
  773 
  774         error = copyinstr(SCARG(uap, name), attrname, sizeof(attrname),
  775             NULL);
  776         if (error)
  777                 return (error);
  778 
  779         NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), l);
  780         error = namei(&nd);
  781         if (error)
  782                 return (error);
  783 
  784         /* XXX flags */
  785 
  786         error = extattr_set_vp(nd.ni_vp, EXTATTR_NAMESPACE_USER,
  787             attrname, SCARG(uap, value), SCARG(uap, size), l, retval);
  788 
  789         vrele(nd.ni_vp);
  790         return (error);
  791 }
  792 
  793 int
  794 sys_lsetxattr(struct lwp *l, void *v, register_t *retval)
  795 {
  796         struct sys_lsetxattr_args /* {
  797                 syscallarg(const char *) path;
  798                 syscallarg(const char *) name;
  799                 syscallarg(void *) value;
  800                 syscallarg(size_t) size;
  801                 syscallarg(int) flags;
  802         } */ *uap = v;
  803         struct nameidata nd;
  804         char attrname[XATTR_NAME_MAX];
  805         int error;
  806 
  807         error = copyinstr(SCARG(uap, name), attrname, sizeof(attrname),
  808             NULL);
  809         if (error)
  810                 return (error);
  811 
  812         NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), l);
  813         error = namei(&nd);
  814         if (error)
  815                 return (error);
  816 
  817         /* XXX flags */
  818 
  819         error = extattr_set_vp(nd.ni_vp, EXTATTR_NAMESPACE_USER,
  820             attrname, SCARG(uap, value), SCARG(uap, size), l, retval);
  821 
  822         vrele(nd.ni_vp);
  823         return (error);
  824 }
  825 
  826 int
  827 sys_fsetxattr(struct lwp *l, void *v, register_t *retval)
  828 {
  829         struct sys_fsetxattr_args /* {
  830                 syscallarg(int) fd;
  831                 syscallarg(const char *) name;
  832                 syscallarg(void *) value;
  833                 syscallarg(size_t) size;
  834                 syscallarg(int) flags;
  835         } */ *uap = v;
  836         struct file *fp;
  837         struct vnode *vp;
  838         char attrname[XATTR_NAME_MAX];
  839         int error;
  840 
  841         error = copyinstr(SCARG(uap, name), attrname, sizeof(attrname),
  842             NULL);
  843         if (error)
  844                 return (error);
  845 
  846         error = getvnode(l->l_proc->p_fd, SCARG(uap, fd), &fp);
  847         if (error)
  848                 return (error);
  849         vp = (struct vnode *) fp->f_data;
  850 
  851         /* XXX flags */
  852 
  853         error = extattr_set_vp(vp, EXTATTR_NAMESPACE_USER,
  854             attrname, SCARG(uap, value), SCARG(uap, size), l, retval);
  855 
  856         FILE_UNUSE(fp, l);
  857         return (error);
  858 }
  859 
  860 int
  861 sys_getxattr(struct lwp *l, void *v, register_t *retval)
  862 {
  863         struct sys_getxattr_args /* {
  864                 syscallarg(const char *) path;
  865                 syscallarg(const char *) name;
  866                 syscallarg(void *) value;
  867                 syscallarg(size_t) size;
  868         } */ *uap = v;
  869         struct nameidata nd;
  870         char attrname[XATTR_NAME_MAX];
  871         int error;
  872 
  873         error = copyinstr(SCARG(uap, name), attrname, sizeof(attrname),
  874             NULL);
  875         if (error)
  876                 return (error);
  877 
  878         NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), l);
  879         error = namei(&nd);
  880         if (error)
  881                 return (error);
  882 
  883         error = extattr_get_vp(nd.ni_vp, EXTATTR_NAMESPACE_USER,
  884             attrname, SCARG(uap, value), SCARG(uap, size), l, retval);
  885 
  886         vrele(nd.ni_vp);
  887         return (error);
  888 }
  889 
  890 int
  891 sys_lgetxattr(struct lwp *l, void *v, register_t *retval)
  892 {
  893         struct sys_lgetxattr_args /* {
  894                 syscallarg(const char *) path;
  895                 syscallarg(const char *) name;
  896                 syscallarg(void *) value;
  897                 syscallarg(size_t) size;
  898         } */ *uap = v;
  899         struct nameidata nd;
  900         char attrname[XATTR_NAME_MAX];
  901         int error;
  902 
  903         error = copyinstr(SCARG(uap, name), attrname, sizeof(attrname),
  904             NULL);
  905         if (error)
  906                 return (error);
  907 
  908         NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), l);
  909         error = namei(&nd);
  910         if (error)
  911                 return (error);
  912 
  913         error = extattr_get_vp(nd.ni_vp, EXTATTR_NAMESPACE_USER,
  914             attrname, SCARG(uap, value), SCARG(uap, size), l, retval);
  915 
  916         vrele(nd.ni_vp);
  917         return (error);
  918 }
  919 
  920 int
  921 sys_fgetxattr(struct lwp *l, void *v, register_t *retval)
  922 {
  923         struct sys_fgetxattr_args /* {
  924                 syscallarg(int) fd;
  925                 syscallarg(const char *) name;
  926                 syscallarg(void *) value;
  927                 syscallarg(size_t) size;
  928         } */ *uap = v;
  929         struct file *fp;
  930         struct vnode *vp;
  931         char attrname[XATTR_NAME_MAX];
  932         int error;
  933 
  934         error = copyinstr(SCARG(uap, name), attrname, sizeof(attrname),
  935             NULL);
  936         if (error)
  937                 return (error);
  938 
  939         error = getvnode(l->l_proc->p_fd, SCARG(uap, fd), &fp);
  940         if (error)
  941                 return (error);
  942         vp = (struct vnode *) fp->f_data;
  943 
  944         error = extattr_get_vp(vp, EXTATTR_NAMESPACE_USER,
  945             attrname, SCARG(uap, value), SCARG(uap, size), l, retval);
  946 
  947         FILE_UNUSE(fp, l);
  948         return (error);
  949 }
  950 
  951 int
  952 sys_listxattr(struct lwp *l, void *v, register_t *retval)
  953 {
  954         struct sys_listxattr_args /* {
  955                 syscallarg(const char *) path;
  956                 syscallarg(char *) list;
  957                 syscallarg(size_t) size;
  958         } */ *uap = v;
  959         struct nameidata nd;
  960         int error;
  961 
  962         NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), l);
  963         error = namei(&nd);
  964         if (error)
  965                 return (error);
  966 
  967         error = extattr_list_vp(nd.ni_vp, EXTATTR_NAMESPACE_USER,
  968             SCARG(uap, list), SCARG(uap, size), l, retval);
  969 
  970         vrele(nd.ni_vp);
  971         return (error);
  972 }
  973 
  974 int
  975 sys_llistxattr(struct lwp *l, void *v, register_t *retval)
  976 {
  977         struct sys_llistxattr_args /* {
  978                 syscallarg(const char *) path;
  979                 syscallarg(char *) list;
  980                 syscallarg(size_t) size;
  981         } */ *uap = v;
  982         struct nameidata nd;
  983         int error;
  984 
  985         NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), l);
  986         error = namei(&nd);
  987         if (error)
  988                 return (error);
  989 
  990         error = extattr_list_vp(nd.ni_vp, EXTATTR_NAMESPACE_USER,
  991             SCARG(uap, list), SCARG(uap, size), l, retval);
  992 
  993         vrele(nd.ni_vp);
  994         return (error);
  995 }
  996 
  997 int
  998 sys_flistxattr(struct lwp *l, void *v, register_t *retval)
  999 {
 1000         struct sys_flistxattr_args /* {
 1001                 syscallarg(int) fd;
 1002                 syscallarg(char *) list;
 1003                 syscallarg(size_t) size;
 1004         } */ *uap = v;
 1005         struct file *fp;
 1006         struct vnode *vp;
 1007         int error;
 1008 
 1009         error = getvnode(l->l_proc->p_fd, SCARG(uap, fd), &fp);
 1010         if (error)
 1011                 return (error);
 1012         vp = (struct vnode *) fp->f_data;
 1013 
 1014         error = extattr_list_vp(vp, EXTATTR_NAMESPACE_USER,
 1015             SCARG(uap, list), SCARG(uap, size), l, retval);
 1016 
 1017         FILE_UNUSE(fp, l);
 1018         return (error);
 1019 }
 1020 
 1021 int
 1022 sys_removexattr(struct lwp *l, void *v, register_t *retval)
 1023 {
 1024         struct sys_removexattr_args /* {
 1025                 syscallarg(const char *) path;
 1026                 syscallarg(const char *) name;
 1027         } */ *uap = v;
 1028         struct nameidata nd;
 1029         char attrname[XATTR_NAME_MAX];
 1030         int error;
 1031 
 1032         error = copyinstr(SCARG(uap, name), attrname, sizeof(attrname),
 1033             NULL);
 1034         if (error)
 1035                 return (error);
 1036 
 1037         NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), l);
 1038         error = namei(&nd);
 1039         if (error)
 1040                 return (error);
 1041 
 1042         error = extattr_delete_vp(nd.ni_vp, EXTATTR_NAMESPACE_USER,
 1043             attrname, l);
 1044 
 1045         vrele(nd.ni_vp);
 1046         return (error);
 1047 }
 1048 
 1049 int
 1050 sys_lremovexattr(struct lwp *l, void *v, register_t *retval)
 1051 {
 1052         struct sys_lremovexattr_args /* {
 1053                 syscallarg(const char *) path;
 1054                 syscallarg(const char *) name;
 1055         } */ *uap = v;
 1056         struct nameidata nd;
 1057         char attrname[XATTR_NAME_MAX];
 1058         int error;
 1059 
 1060         error = copyinstr(SCARG(uap, name), attrname, sizeof(attrname),
 1061             NULL);
 1062         if (error)
 1063                 return (error);
 1064 
 1065         NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, SCARG(uap, path), l);
 1066         error = namei(&nd);
 1067         if (error)
 1068                 return (error);
 1069 
 1070         error = extattr_delete_vp(nd.ni_vp, EXTATTR_NAMESPACE_USER,
 1071             attrname, l);
 1072 
 1073         vrele(nd.ni_vp);
 1074         return (error);
 1075 }
 1076 
 1077 int
 1078 sys_fremovexattr(struct lwp *l, void *v, register_t *retval)
 1079 {
 1080         struct sys_fremovexattr_args /* {
 1081                 syscallarg(int) fd;
 1082                 syscallarg(const char *) name;
 1083         } */ *uap = v;
 1084         struct file *fp;
 1085         struct vnode *vp;
 1086         char attrname[XATTR_NAME_MAX];
 1087         int error;
 1088 
 1089         error = copyinstr(SCARG(uap, name), attrname, sizeof(attrname),
 1090             NULL);
 1091         if (error)
 1092                 return (error);
 1093 
 1094         error = getvnode(l->l_proc->p_fd, SCARG(uap, fd), &fp);
 1095         if (error)
 1096                 return (error);
 1097         vp = (struct vnode *) fp->f_data;
 1098 
 1099         error = extattr_delete_vp(vp, EXTATTR_NAMESPACE_USER,
 1100             attrname, l);
 1101 
 1102         FILE_UNUSE(fp, l);
 1103         return (error);
 1104 }

Cache object: 09940aa599b6ac9185595c8d5de82d39


[ 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.