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


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

FreeBSD/Linux Kernel Cross Reference
sys/contrib/openzfs/module/os/freebsd/zfs/zfs_file_os.c

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

    1 /*
    2  * Copyright (c) 2020 iXsystems, Inc.
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  *
   26  */
   27 
   28 #include <sys/cdefs.h>
   29 __FBSDID("$FreeBSD$");
   30 
   31 #include <sys/dmu.h>
   32 #include <sys/dmu_impl.h>
   33 #include <sys/dmu_recv.h>
   34 #include <sys/dmu_tx.h>
   35 #include <sys/dbuf.h>
   36 #include <sys/dnode.h>
   37 #include <sys/zfs_context.h>
   38 #include <sys/dmu_objset.h>
   39 #include <sys/dmu_traverse.h>
   40 #include <sys/dsl_dataset.h>
   41 #include <sys/dsl_dir.h>
   42 #include <sys/dsl_pool.h>
   43 #include <sys/dsl_synctask.h>
   44 #include <sys/zfs_ioctl.h>
   45 #include <sys/zap.h>
   46 #include <sys/zio_checksum.h>
   47 #include <sys/zfs_znode.h>
   48 #include <sys/zfs_file.h>
   49 #include <sys/buf.h>
   50 #include <sys/stat.h>
   51 
   52 int
   53 zfs_file_open(const char *path, int flags, int mode, zfs_file_t **fpp)
   54 {
   55         struct thread *td;
   56         int rc, fd;
   57 
   58         td = curthread;
   59         pwd_ensure_dirs();
   60         /* 12.x doesn't take a const char * */
   61         rc = kern_openat(td, AT_FDCWD, __DECONST(char *, path),
   62             UIO_SYSSPACE, flags, mode);
   63         if (rc)
   64                 return (SET_ERROR(rc));
   65         fd = td->td_retval[0];
   66         td->td_retval[0] = 0;
   67         if (fget(curthread, fd, &cap_no_rights, fpp))
   68                 kern_close(td, fd);
   69         return (0);
   70 }
   71 
   72 void
   73 zfs_file_close(zfs_file_t *fp)
   74 {
   75         fo_close(fp, curthread);
   76 }
   77 
   78 static int
   79 zfs_file_write_impl(zfs_file_t *fp, const void *buf, size_t count, loff_t *offp,
   80     ssize_t *resid)
   81 {
   82         ssize_t rc;
   83         struct uio auio;
   84         struct thread *td;
   85         struct iovec aiov;
   86 
   87         td = curthread;
   88         aiov.iov_base = (void *)(uintptr_t)buf;
   89         aiov.iov_len = count;
   90         auio.uio_iov = &aiov;
   91         auio.uio_iovcnt = 1;
   92         auio.uio_segflg = UIO_SYSSPACE;
   93         auio.uio_resid = count;
   94         auio.uio_rw = UIO_WRITE;
   95         auio.uio_td = td;
   96         auio.uio_offset = *offp;
   97 
   98         if ((fp->f_flag & FWRITE) == 0)
   99                 return (SET_ERROR(EBADF));
  100 
  101         if (fp->f_type == DTYPE_VNODE)
  102                 bwillwrite();
  103 
  104         rc = fo_write(fp, &auio, td->td_ucred, FOF_OFFSET, td);
  105         if (rc)
  106                 return (SET_ERROR(rc));
  107         if (resid)
  108                 *resid = auio.uio_resid;
  109         else if (auio.uio_resid)
  110                 return (SET_ERROR(EIO));
  111         *offp += count - auio.uio_resid;
  112         return (rc);
  113 }
  114 
  115 int
  116 zfs_file_write(zfs_file_t *fp, const void *buf, size_t count, ssize_t *resid)
  117 {
  118         loff_t off = fp->f_offset;
  119         ssize_t rc;
  120 
  121         rc = zfs_file_write_impl(fp, buf, count, &off, resid);
  122         if (rc == 0)
  123                 fp->f_offset = off;
  124 
  125         return (SET_ERROR(rc));
  126 }
  127 
  128 int
  129 zfs_file_pwrite(zfs_file_t *fp, const void *buf, size_t count, loff_t off,
  130     ssize_t *resid)
  131 {
  132         return (zfs_file_write_impl(fp, buf, count, &off, resid));
  133 }
  134 
  135 static int
  136 zfs_file_read_impl(zfs_file_t *fp, void *buf, size_t count, loff_t *offp,
  137     ssize_t *resid)
  138 {
  139         ssize_t rc;
  140         struct uio auio;
  141         struct thread *td;
  142         struct iovec aiov;
  143 
  144         td = curthread;
  145         aiov.iov_base = (void *)(uintptr_t)buf;
  146         aiov.iov_len = count;
  147         auio.uio_iov = &aiov;
  148         auio.uio_iovcnt = 1;
  149         auio.uio_segflg = UIO_SYSSPACE;
  150         auio.uio_resid = count;
  151         auio.uio_rw = UIO_READ;
  152         auio.uio_td = td;
  153         auio.uio_offset = *offp;
  154 
  155         if ((fp->f_flag & FREAD) == 0)
  156                 return (SET_ERROR(EBADF));
  157 
  158         rc = fo_read(fp, &auio, td->td_ucred, FOF_OFFSET, td);
  159         if (rc)
  160                 return (SET_ERROR(rc));
  161         if (resid)
  162                 *resid = auio.uio_resid;
  163         *offp += count - auio.uio_resid;
  164         return (SET_ERROR(0));
  165 }
  166 
  167 int
  168 zfs_file_read(zfs_file_t *fp, void *buf, size_t count, ssize_t *resid)
  169 {
  170         loff_t off = fp->f_offset;
  171         ssize_t rc;
  172 
  173         rc = zfs_file_read_impl(fp, buf, count, &off, resid);
  174         if (rc == 0)
  175                 fp->f_offset = off;
  176         return (rc);
  177 }
  178 
  179 int
  180 zfs_file_pread(zfs_file_t *fp, void *buf, size_t count, loff_t off,
  181     ssize_t *resid)
  182 {
  183         return (zfs_file_read_impl(fp, buf, count, &off, resid));
  184 }
  185 
  186 int
  187 zfs_file_seek(zfs_file_t *fp, loff_t *offp, int whence)
  188 {
  189         int rc;
  190         struct thread *td;
  191 
  192         td = curthread;
  193         if ((fp->f_ops->fo_flags & DFLAG_SEEKABLE) == 0)
  194                 return (SET_ERROR(ESPIPE));
  195         rc = fo_seek(fp, *offp, whence, td);
  196         if (rc == 0)
  197                 *offp = td->td_uretoff.tdu_off;
  198         return (SET_ERROR(rc));
  199 }
  200 
  201 int
  202 zfs_file_getattr(zfs_file_t *fp, zfs_file_attr_t *zfattr)
  203 {
  204         struct thread *td;
  205         struct stat sb;
  206         int rc;
  207 
  208         td = curthread;
  209 
  210 #if __FreeBSD_version < 1400037
  211         rc = fo_stat(fp, &sb, td->td_ucred, td);
  212 #else
  213         rc = fo_stat(fp, &sb, td->td_ucred);
  214 #endif
  215         if (rc)
  216                 return (SET_ERROR(rc));
  217         zfattr->zfa_size = sb.st_size;
  218         zfattr->zfa_mode = sb.st_mode;
  219 
  220         return (0);
  221 }
  222 
  223 static __inline int
  224 zfs_vop_fsync(vnode_t *vp)
  225 {
  226         struct mount *mp;
  227         int error;
  228 
  229 #if __FreeBSD_version < 1400068
  230         if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
  231 #else
  232         if ((error = vn_start_write(vp, &mp, V_WAIT | V_PCATCH)) != 0)
  233 #endif
  234                 goto drop;
  235         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
  236         error = VOP_FSYNC(vp, MNT_WAIT, curthread);
  237         VOP_UNLOCK1(vp);
  238         vn_finished_write(mp);
  239 drop:
  240         return (SET_ERROR(error));
  241 }
  242 
  243 int
  244 zfs_file_fsync(zfs_file_t *fp, int flags)
  245 {
  246         if (fp->f_type != DTYPE_VNODE)
  247                 return (EINVAL);
  248 
  249         return (zfs_vop_fsync(fp->f_vnode));
  250 }
  251 
  252 zfs_file_t *
  253 zfs_file_get(int fd)
  254 {
  255         struct file *fp;
  256 
  257         if (fget(curthread, fd, &cap_no_rights, &fp))
  258                 return (NULL);
  259 
  260         return (fp);
  261 }
  262 
  263 void
  264 zfs_file_put(zfs_file_t *fp)
  265 {
  266         fdrop(fp, curthread);
  267 }
  268 
  269 loff_t
  270 zfs_file_off(zfs_file_t *fp)
  271 {
  272         return (fp->f_offset);
  273 }
  274 
  275 void *
  276 zfs_file_private(zfs_file_t *fp)
  277 {
  278         file_t *tmpfp;
  279         void *data;
  280         int error;
  281 
  282         tmpfp = curthread->td_fpop;
  283         curthread->td_fpop = fp;
  284         error = devfs_get_cdevpriv(&data);
  285         curthread->td_fpop = tmpfp;
  286         if (error != 0)
  287                 return (NULL);
  288         return (data);
  289 }
  290 
  291 int
  292 zfs_file_unlink(const char *fnamep)
  293 {
  294         zfs_uio_seg_t seg = UIO_SYSSPACE;
  295         int rc;
  296 
  297 #if __FreeBSD_version >= 1300018
  298         rc = kern_funlinkat(curthread, AT_FDCWD, fnamep, FD_NONE, seg, 0, 0);
  299 #elif __FreeBSD_version >= 1202504 || defined(AT_BENEATH)
  300         rc = kern_unlinkat(curthread, AT_FDCWD, __DECONST(char *, fnamep),
  301             seg, 0, 0);
  302 #else
  303         rc = kern_unlinkat(curthread, AT_FDCWD, __DECONST(char *, fnamep),
  304             seg, 0);
  305 #endif
  306         return (SET_ERROR(rc));
  307 }

Cache object: 42682ef88b1d03d983d0dc66d77dcb65


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