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