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

Cache object: 5b7458c3ccdd781e41165adf2ae8ab17


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