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/linux/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  * CDDL HEADER START
    3  *
    4  * The contents of this file are subject to the terms of the
    5  * Common Development and Distribution License (the "License").
    6  * You may not use this file except in compliance with the License.
    7  *
    8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
    9  * or https://opensource.org/licenses/CDDL-1.0.
   10  * See the License for the specific language governing permissions
   11  * and limitations under the License.
   12  *
   13  * When distributing Covered Code, include this CDDL HEADER in each
   14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
   15  * If applicable, add the following below this CDDL HEADER, with the
   16  * fields enclosed by brackets "[]" replaced with your own identifying
   17  * information: Portions Copyright [yyyy] [name of copyright owner]
   18  *
   19  * CDDL HEADER END
   20  */
   21 
   22 #include <sys/zfs_context.h>
   23 #include <sys/zfs_file.h>
   24 #include <sys/stat.h>
   25 #include <sys/file.h>
   26 #include <linux/falloc.h>
   27 #include <linux/fs.h>
   28 #include <linux/uaccess.h>
   29 #ifdef HAVE_FDTABLE_HEADER
   30 #include <linux/fdtable.h>
   31 #endif
   32 
   33 /*
   34  * Open file
   35  *
   36  * path - fully qualified path to file
   37  * flags - file attributes O_READ / O_WRITE / O_EXCL
   38  * fpp - pointer to return file pointer
   39  *
   40  * Returns 0 on success underlying error on failure.
   41  */
   42 int
   43 zfs_file_open(const char *path, int flags, int mode, zfs_file_t **fpp)
   44 {
   45         struct file *filp;
   46         int saved_umask;
   47 
   48         if (!(flags & O_CREAT) && (flags & O_WRONLY))
   49                 flags |= O_EXCL;
   50 
   51         if (flags & O_CREAT)
   52                 saved_umask = xchg(&current->fs->umask, 0);
   53 
   54         filp = filp_open(path, flags, mode);
   55 
   56         if (flags & O_CREAT)
   57                 (void) xchg(&current->fs->umask, saved_umask);
   58 
   59         if (IS_ERR(filp))
   60                 return (-PTR_ERR(filp));
   61 
   62         *fpp = filp;
   63         return (0);
   64 }
   65 
   66 void
   67 zfs_file_close(zfs_file_t *fp)
   68 {
   69         filp_close(fp, 0);
   70 }
   71 
   72 static ssize_t
   73 zfs_file_write_impl(zfs_file_t *fp, const void *buf, size_t count, loff_t *off)
   74 {
   75 #if defined(HAVE_KERNEL_WRITE_PPOS)
   76         return (kernel_write(fp, buf, count, off));
   77 #else
   78         mm_segment_t saved_fs;
   79         ssize_t rc;
   80 
   81         saved_fs = get_fs();
   82         set_fs(KERNEL_DS);
   83 
   84         rc = vfs_write(fp, (__force const char __user __user *)buf, count, off);
   85 
   86         set_fs(saved_fs);
   87 
   88         return (rc);
   89 #endif
   90 }
   91 
   92 /*
   93  * Stateful write - use os internal file pointer to determine where to
   94  * write and update on successful completion.
   95  *
   96  * fp -  pointer to file (pipe, socket, etc) to write to
   97  * buf - buffer to write
   98  * count - # of bytes to write
   99  * resid -  pointer to count of unwritten bytes  (if short write)
  100  *
  101  * Returns 0 on success errno on failure.
  102  */
  103 int
  104 zfs_file_write(zfs_file_t *fp, const void *buf, size_t count, ssize_t *resid)
  105 {
  106         loff_t off = fp->f_pos;
  107         ssize_t rc;
  108 
  109         rc = zfs_file_write_impl(fp, buf, count, &off);
  110         if (rc < 0)
  111                 return (-rc);
  112 
  113         fp->f_pos = off;
  114 
  115         if (resid) {
  116                 *resid = count - rc;
  117         } else if (rc != count) {
  118                 return (EIO);
  119         }
  120 
  121         return (0);
  122 }
  123 
  124 /*
  125  * Stateless write - os internal file pointer is not updated.
  126  *
  127  * fp -  pointer to file (pipe, socket, etc) to write to
  128  * buf - buffer to write
  129  * count - # of bytes to write
  130  * off - file offset to write to (only valid for seekable types)
  131  * resid -  pointer to count of unwritten bytes
  132  *
  133  * Returns 0 on success errno on failure.
  134  */
  135 int
  136 zfs_file_pwrite(zfs_file_t *fp, const void *buf, size_t count, loff_t off,
  137     ssize_t *resid)
  138 {
  139         ssize_t rc;
  140 
  141         rc  = zfs_file_write_impl(fp, buf, count, &off);
  142         if (rc < 0)
  143                 return (-rc);
  144 
  145         if (resid) {
  146                 *resid = count - rc;
  147         } else if (rc != count) {
  148                 return (EIO);
  149         }
  150 
  151         return (0);
  152 }
  153 
  154 static ssize_t
  155 zfs_file_read_impl(zfs_file_t *fp, void *buf, size_t count, loff_t *off)
  156 {
  157 #if defined(HAVE_KERNEL_READ_PPOS)
  158         return (kernel_read(fp, buf, count, off));
  159 #else
  160         mm_segment_t saved_fs;
  161         ssize_t rc;
  162 
  163         saved_fs = get_fs();
  164         set_fs(KERNEL_DS);
  165 
  166         rc = vfs_read(fp, (void __user *)buf, count, off);
  167         set_fs(saved_fs);
  168 
  169         return (rc);
  170 #endif
  171 }
  172 
  173 /*
  174  * Stateful read - use os internal file pointer to determine where to
  175  * read and update on successful completion.
  176  *
  177  * fp -  pointer to file (pipe, socket, etc) to read from
  178  * buf - buffer to write
  179  * count - # of bytes to read
  180  * resid -  pointer to count of unread bytes (if short read)
  181  *
  182  * Returns 0 on success errno on failure.
  183  */
  184 int
  185 zfs_file_read(zfs_file_t *fp, void *buf, size_t count, ssize_t *resid)
  186 {
  187         loff_t off = fp->f_pos;
  188         ssize_t rc;
  189 
  190         rc = zfs_file_read_impl(fp, buf, count, &off);
  191         if (rc < 0)
  192                 return (-rc);
  193 
  194         fp->f_pos = off;
  195 
  196         if (resid) {
  197                 *resid = count - rc;
  198         } else if (rc != count) {
  199                 return (EIO);
  200         }
  201 
  202         return (0);
  203 }
  204 
  205 /*
  206  * Stateless read - os internal file pointer is not updated.
  207  *
  208  * fp -  pointer to file (pipe, socket, etc) to read from
  209  * buf - buffer to write
  210  * count - # of bytes to write
  211  * off - file offset to read from (only valid for seekable types)
  212  * resid -  pointer to count of unwritten bytes (if short write)
  213  *
  214  * Returns 0 on success errno on failure.
  215  */
  216 int
  217 zfs_file_pread(zfs_file_t *fp, void *buf, size_t count, loff_t off,
  218     ssize_t *resid)
  219 {
  220         ssize_t rc;
  221 
  222         rc = zfs_file_read_impl(fp, buf, count, &off);
  223         if (rc < 0)
  224                 return (-rc);
  225 
  226         if (resid) {
  227                 *resid = count - rc;
  228         } else if (rc != count) {
  229                 return (EIO);
  230         }
  231 
  232         return (0);
  233 }
  234 
  235 /*
  236  * lseek - set / get file pointer
  237  *
  238  * fp -  pointer to file (pipe, socket, etc) to read from
  239  * offp - value to seek to, returns current value plus passed offset
  240  * whence - see man pages for standard lseek whence values
  241  *
  242  * Returns 0 on success errno on failure (ESPIPE for non seekable types)
  243  */
  244 int
  245 zfs_file_seek(zfs_file_t *fp, loff_t *offp, int whence)
  246 {
  247         loff_t rc;
  248 
  249         if (*offp < 0)
  250                 return (EINVAL);
  251 
  252         rc = vfs_llseek(fp, *offp, whence);
  253         if (rc < 0)
  254                 return (-rc);
  255 
  256         *offp = rc;
  257 
  258         return (0);
  259 }
  260 
  261 /*
  262  * Get file attributes
  263  *
  264  * filp - file pointer
  265  * zfattr - pointer to file attr structure
  266  *
  267  * Currently only used for fetching size and file mode.
  268  *
  269  * Returns 0 on success or error code of underlying getattr call on failure.
  270  */
  271 int
  272 zfs_file_getattr(zfs_file_t *filp, zfs_file_attr_t *zfattr)
  273 {
  274         struct kstat stat;
  275         int rc;
  276 
  277 #if defined(HAVE_4ARGS_VFS_GETATTR)
  278         rc = vfs_getattr(&filp->f_path, &stat, STATX_BASIC_STATS,
  279             AT_STATX_SYNC_AS_STAT);
  280 #elif defined(HAVE_2ARGS_VFS_GETATTR)
  281         rc = vfs_getattr(&filp->f_path, &stat);
  282 #elif defined(HAVE_3ARGS_VFS_GETATTR)
  283         rc = vfs_getattr(filp->f_path.mnt, filp->f_dentry, &stat);
  284 #else
  285 #error "No available vfs_getattr()"
  286 #endif
  287         if (rc)
  288                 return (-rc);
  289 
  290         zfattr->zfa_size = stat.size;
  291         zfattr->zfa_mode = stat.mode;
  292 
  293         return (0);
  294 }
  295 
  296 /*
  297  * Sync file to disk
  298  *
  299  * filp - file pointer
  300  * flags - O_SYNC and or O_DSYNC
  301  *
  302  * Returns 0 on success or error code of underlying sync call on failure.
  303  */
  304 int
  305 zfs_file_fsync(zfs_file_t *filp, int flags)
  306 {
  307         int datasync = 0;
  308         int error;
  309         int fstrans;
  310 
  311         if (flags & O_DSYNC)
  312                 datasync = 1;
  313 
  314         /*
  315          * May enter XFS which generates a warning when PF_FSTRANS is set.
  316          * To avoid this the flag is cleared over vfs_sync() and then reset.
  317          */
  318         fstrans = __spl_pf_fstrans_check();
  319         if (fstrans)
  320                 current->flags &= ~(__SPL_PF_FSTRANS);
  321 
  322         error = -vfs_fsync(filp, datasync);
  323 
  324         if (fstrans)
  325                 current->flags |= __SPL_PF_FSTRANS;
  326 
  327         return (error);
  328 }
  329 
  330 /*
  331  * fallocate - allocate or free space on disk
  332  *
  333  * fp - file pointer
  334  * mode (non-standard options for hole punching etc)
  335  * offset - offset to start allocating or freeing from
  336  * len - length to free / allocate
  337  *
  338  * OPTIONAL
  339  */
  340 int
  341 zfs_file_fallocate(zfs_file_t *fp, int mode, loff_t offset, loff_t len)
  342 {
  343         /*
  344          * May enter XFS which generates a warning when PF_FSTRANS is set.
  345          * To avoid this the flag is cleared over vfs_sync() and then reset.
  346          */
  347         int fstrans = __spl_pf_fstrans_check();
  348         if (fstrans)
  349                 current->flags &= ~(__SPL_PF_FSTRANS);
  350 
  351         /*
  352          * When supported by the underlying file system preferentially
  353          * use the fallocate() callback to preallocate the space.
  354          */
  355         int error = EOPNOTSUPP;
  356         if (fp->f_op->fallocate)
  357                 error = fp->f_op->fallocate(fp, mode, offset, len);
  358 
  359         if (fstrans)
  360                 current->flags |= __SPL_PF_FSTRANS;
  361 
  362         return (error);
  363 }
  364 
  365 /*
  366  * Request current file pointer offset
  367  *
  368  * fp - pointer to file
  369  *
  370  * Returns current file offset.
  371  */
  372 loff_t
  373 zfs_file_off(zfs_file_t *fp)
  374 {
  375         return (fp->f_pos);
  376 }
  377 
  378 /*
  379  * Request file pointer private data
  380  *
  381  * fp - pointer to file
  382  *
  383  * Returns pointer to file private data.
  384  */
  385 void *
  386 zfs_file_private(zfs_file_t *fp)
  387 {
  388         return (fp->private_data);
  389 }
  390 
  391 /*
  392  * unlink file
  393  *
  394  * path - fully qualified file path
  395  *
  396  * Returns 0 on success.
  397  *
  398  * OPTIONAL
  399  */
  400 int
  401 zfs_file_unlink(const char *path)
  402 {
  403         return (EOPNOTSUPP);
  404 }
  405 
  406 /*
  407  * Get reference to file pointer
  408  *
  409  * fd - input file descriptor
  410  *
  411  * Returns pointer to file struct or NULL
  412  */
  413 zfs_file_t *
  414 zfs_file_get(int fd)
  415 {
  416         return (fget(fd));
  417 }
  418 
  419 /*
  420  * Drop reference to file pointer
  421  *
  422  * fp - input file struct pointer
  423  */
  424 void
  425 zfs_file_put(zfs_file_t *fp)
  426 {
  427         fput(fp);
  428 }

Cache object: 1d2f0b89187b164fbd95536f19f003c0


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