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(¤t->fs->umask, 0); 53 54 filp = filp_open(path, flags, mode); 55 56 if (flags & O_CREAT) 57 (void) xchg(¤t->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 || *offp > MAXOFFSET_T) 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 } 429