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/compat/linuxkpi/common/src/linux_simple_attr.c

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

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2022, Jake Freeland <jfree@freebsd.org>
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   25  * SUCH DAMAGE.
   26  */
   27 
   28 #include <sys/cdefs.h>
   29 __FBSDID("$FreeBSD$");
   30 
   31 #include <sys/types.h>
   32 #include <linux/fs.h>
   33 
   34 MALLOC_DEFINE(M_LSATTR, "simple_attr", "Linux Simple Attribute File");
   35 
   36 struct simple_attr {
   37         int (*get)(void *, uint64_t *);
   38         int (*set)(void *, uint64_t);
   39         void *data;
   40         const char *fmt;
   41         struct mutex mutex;
   42 };
   43 
   44 /*
   45  * simple_attr_open: open and populate simple attribute data
   46  *
   47  * @inode: file inode
   48  * @filp: file pointer
   49  * @get: ->get() for reading file data
   50  * @set: ->set() for writing file data
   51  * @fmt: format specifier for data returned by @get
   52  *
   53  * Memory allocate a simple_attr and appropriately initialize its members.
   54  * The simple_attr must be stored in filp->private_data.
   55  * Simple attr files do not support seeking. Open the file as nonseekable.
   56  *
   57  * Return value: simple attribute file descriptor
   58  */
   59 int
   60 simple_attr_open(struct inode *inode, struct file *filp,
   61     int (*get)(void *, uint64_t *), int (*set)(void *, uint64_t),
   62     const char *fmt)
   63 {
   64         struct simple_attr *sattr;
   65         sattr = malloc(sizeof(*sattr), M_LSATTR, M_ZERO | M_NOWAIT);
   66         if (sattr == NULL)
   67                 return (-ENOMEM);
   68 
   69         sattr->get = get;
   70         sattr->set = set;
   71         sattr->data = inode->i_private;
   72         sattr->fmt = fmt;
   73         mutex_init(&sattr->mutex);
   74 
   75         filp->private_data = (void *) sattr;
   76 
   77         return (nonseekable_open(inode, filp));
   78 }
   79 
   80 int
   81 simple_attr_release(struct inode *inode, struct file *filp)
   82 {
   83         free(filp->private_data, M_LSATTR);
   84         return (0);
   85 }
   86 
   87 /*
   88  * simple_attr_read: read simple attr data and transfer into buffer
   89  *
   90  * @filp: file pointer
   91  * @buf: kernel space buffer
   92  * @read_size: number of bytes to be transferred
   93  * @ppos: starting pointer position for transfer
   94  *
   95  * The simple_attr structure is stored in filp->private_data.
   96  * ->get() retrieves raw file data.
   97  * The ->fmt specifier can format this data to be human readable.
   98  * This output is then transferred into the @buf buffer.
   99  *
  100  * Return value:
  101  * On success, number of bytes transferred
  102  * On failure, negative signed ERRNO
  103  */
  104 ssize_t
  105 simple_attr_read(struct file *filp, char *buf, size_t read_size, loff_t *ppos)
  106 {
  107         struct simple_attr *sattr;
  108         uint64_t data;
  109         ssize_t ret;
  110         char prebuf[24];
  111 
  112         sattr = filp->private_data;
  113 
  114         if (sattr->get == NULL)
  115                 return (-EFAULT);
  116 
  117         mutex_lock(&sattr->mutex);
  118 
  119         ret = sattr->get(sattr->data, &data);
  120         if (ret)
  121                 goto unlock;
  122 
  123         scnprintf(prebuf, sizeof(prebuf), sattr->fmt, data);
  124 
  125         ret = strlen(prebuf) + 1;
  126         if (*ppos >= ret || read_size < 1) {
  127                 ret = -EINVAL;
  128                 goto unlock;
  129         }
  130 
  131         read_size = min(ret - *ppos, read_size);
  132         ret = strscpy(buf, prebuf + *ppos, read_size);
  133 
  134         /* add 1 for null terminator */
  135         if (ret > 0)
  136                 ret += 1;
  137 
  138 unlock:
  139         mutex_unlock(&sattr->mutex);
  140         return (ret);
  141 }
  142 
  143 /*
  144  * simple_attr_write: write contents of buffer into simple attribute file
  145  *
  146  * @filp: file pointer
  147  * @buf: kernel space buffer
  148  * @write_size: number bytes to be transferred
  149  * @ppos: starting pointer position for transfer
  150  *
  151  * The simple_attr structure is stored in filp->private_data.
  152  * Convert the @buf string to unsigned long long.
  153  * ->set() writes unsigned long long data into the simple attr file.
  154  *
  155  * Return value:
  156  * On success, number of bytes written to simple attr
  157  * On failure, negative signed ERRNO
  158  */
  159 ssize_t
  160 simple_attr_write(struct file *filp, const char *buf, size_t write_size, loff_t *ppos)
  161 {
  162         struct simple_attr *sattr;
  163         unsigned long long data;
  164         size_t bufsize;
  165         ssize_t ret;
  166 
  167         sattr = filp->private_data;
  168         bufsize = strlen(buf) + 1;
  169 
  170         if (sattr->set == NULL)
  171                 return (-EFAULT);
  172 
  173         if (*ppos >= bufsize || write_size < 1)
  174                 return (-EINVAL);
  175 
  176         mutex_lock(&sattr->mutex);
  177 
  178         ret = kstrtoull(buf + *ppos, 0, &data);
  179         if (ret)
  180                 goto unlock;
  181 
  182         ret = sattr->set(sattr->data, data);
  183         if (ret)
  184                 goto unlock;
  185 
  186         ret = bufsize - *ppos;
  187 
  188 unlock:
  189         mutex_unlock(&sattr->mutex);
  190         return (ret);
  191 }

Cache object: d2ff0e21c93173aa74329e09d9fddd2f


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