vfs_vnops.c (abbb57d5a647f91847a860bd25b4f109c3abb390) | vfs_vnops.c (0dc332bff200c940edc36c4715b629a2e1e9f9ae) |
---|---|
1/*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 1982, 1986, 1989, 1993 5 * The Regents of the University of California. All rights reserved. 6 * (c) UNIX System Laboratories, Inc. 7 * All or some portions of this file are derived from material licensed 8 * to the University of California by American Telephone and Telegraph --- 92 unchanged lines hidden (view full) --- 101static fo_rdwr_t vn_io_fault; 102static fo_truncate_t vn_truncate; 103static fo_ioctl_t vn_ioctl; 104static fo_poll_t vn_poll; 105static fo_kqfilter_t vn_kqfilter; 106static fo_close_t vn_closefile; 107static fo_mmap_t vn_mmap; 108static fo_fallocate_t vn_fallocate; | 1/*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 1982, 1986, 1989, 1993 5 * The Regents of the University of California. All rights reserved. 6 * (c) UNIX System Laboratories, Inc. 7 * All or some portions of this file are derived from material licensed 8 * to the University of California by American Telephone and Telegraph --- 92 unchanged lines hidden (view full) --- 101static fo_rdwr_t vn_io_fault; 102static fo_truncate_t vn_truncate; 103static fo_ioctl_t vn_ioctl; 104static fo_poll_t vn_poll; 105static fo_kqfilter_t vn_kqfilter; 106static fo_close_t vn_closefile; 107static fo_mmap_t vn_mmap; 108static fo_fallocate_t vn_fallocate; |
109static fo_fspacectl_t vn_fspacectl; |
|
109 110struct fileops vnops = { 111 .fo_read = vn_io_fault, 112 .fo_write = vn_io_fault, 113 .fo_truncate = vn_truncate, 114 .fo_ioctl = vn_ioctl, 115 .fo_poll = vn_poll, 116 .fo_kqfilter = vn_kqfilter, 117 .fo_stat = vn_statfile, 118 .fo_close = vn_closefile, 119 .fo_chmod = vn_chmod, 120 .fo_chown = vn_chown, 121 .fo_sendfile = vn_sendfile, 122 .fo_seek = vn_seek, 123 .fo_fill_kinfo = vn_fill_kinfo, 124 .fo_mmap = vn_mmap, 125 .fo_fallocate = vn_fallocate, | 110 111struct fileops vnops = { 112 .fo_read = vn_io_fault, 113 .fo_write = vn_io_fault, 114 .fo_truncate = vn_truncate, 115 .fo_ioctl = vn_ioctl, 116 .fo_poll = vn_poll, 117 .fo_kqfilter = vn_kqfilter, 118 .fo_stat = vn_statfile, 119 .fo_close = vn_closefile, 120 .fo_chmod = vn_chmod, 121 .fo_chown = vn_chown, 122 .fo_sendfile = vn_sendfile, 123 .fo_seek = vn_seek, 124 .fo_fill_kinfo = vn_fill_kinfo, 125 .fo_mmap = vn_mmap, 126 .fo_fallocate = vn_fallocate, |
127 .fo_fspacectl = vn_fspacectl, |
|
126 .fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE 127}; 128 129const u_int io_hold_cnt = 16; 130static int vn_io_fault_enable = 1; 131SYSCTL_INT(_debug, OID_AUTO, vn_io_fault_enable, CTLFLAG_RWTUN, 132 &vn_io_fault_enable, 0, "Enable vn_io_fault lock avoidance"); 133static int vn_io_fault_prefault = 0; --- 3300 unchanged lines hidden (view full) --- 3434 break; 3435 KASSERT(olen > len, ("Iteration did not make progress?")); 3436 maybe_yield(); 3437 } 3438 3439 return (error); 3440} 3441 | 128 .fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE 129}; 130 131const u_int io_hold_cnt = 16; 132static int vn_io_fault_enable = 1; 133SYSCTL_INT(_debug, OID_AUTO, vn_io_fault_enable, CTLFLAG_RWTUN, 134 &vn_io_fault_enable, 0, "Enable vn_io_fault lock avoidance"); 135static int vn_io_fault_prefault = 0; --- 3300 unchanged lines hidden (view full) --- 3436 break; 3437 KASSERT(olen > len, ("Iteration did not make progress?")); 3438 maybe_yield(); 3439 } 3440 3441 return (error); 3442} 3443 |
3444static int 3445vn_deallocate_impl(struct vnode *vp, off_t *offset, off_t *length, int flags, 3446 int ioflg, struct ucred *active_cred, struct ucred *file_cred) 3447{ 3448 struct mount *mp; 3449 void *rl_cookie; 3450 off_t off, len; 3451 int error; 3452#ifdef AUDIT 3453 bool audited_vnode1 = false; 3454#endif 3455 3456 rl_cookie = NULL; 3457 error = 0; 3458 mp = NULL; 3459 off = *offset; 3460 len = *length; 3461 3462 if ((ioflg & (IO_NODELOCKED|IO_RANGELOCKED)) == 0) 3463 rl_cookie = vn_rangelock_wlock(vp, off, off + len); 3464 while (len > 0 && error == 0) { 3465 /* 3466 * Try to deallocate the longest range in one pass. 3467 * In case a pass takes too long to be executed, it returns 3468 * partial result. The residue will be proceeded in the next 3469 * pass. 3470 */ 3471 3472 if ((ioflg & IO_NODELOCKED) == 0) { 3473 bwillwrite(); 3474 if ((error = vn_start_write(vp, &mp, 3475 V_WAIT | PCATCH)) != 0) 3476 goto out; 3477 vn_lock(vp, vn_lktype_write(mp, vp) | LK_RETRY); 3478 } 3479#ifdef AUDIT 3480 if (!audited_vnode1) { 3481 AUDIT_ARG_VNODE1(vp); 3482 audited_vnode1 = true; 3483 } 3484#endif 3485 3486#ifdef MAC 3487 if ((ioflg & IO_NOMACCHECK) == 0) 3488 error = mac_vnode_check_write(active_cred, file_cred, 3489 vp); 3490#endif 3491 if (error == 0) 3492 error = VOP_DEALLOCATE(vp, &off, &len, flags, 3493 active_cred); 3494 3495 if ((ioflg & IO_NODELOCKED) == 0) { 3496 VOP_UNLOCK(vp); 3497 if (mp != NULL) { 3498 vn_finished_write(mp); 3499 mp = NULL; 3500 } 3501 } 3502 } 3503out: 3504 if (rl_cookie != NULL) 3505 vn_rangelock_unlock(vp, rl_cookie); 3506 *offset = off; 3507 *length = len; 3508 return (error); 3509} 3510 3511int 3512vn_deallocate(struct vnode *vp, off_t *offset, off_t *length, int flags, 3513 int ioflg, struct ucred *active_cred, struct ucred *file_cred) 3514{ 3515 if (*offset < 0 || *length <= 0 || *length > OFF_MAX - *offset || 3516 flags != 0) 3517 return (EINVAL); 3518 if (vp->v_type != VREG) 3519 return (ENODEV); 3520 3521 return (vn_deallocate_impl(vp, offset, length, flags, ioflg, 3522 active_cred, file_cred)); 3523} 3524 3525static int 3526vn_fspacectl(struct file *fp, int cmd, off_t *offset, off_t *length, int flags, 3527 struct ucred *active_cred, struct thread *td) 3528{ 3529 int error; 3530 struct vnode *vp; 3531 3532 vp = fp->f_vnode; 3533 3534 if (cmd != SPACECTL_DEALLOC || *offset < 0 || *length <= 0 || 3535 *length > OFF_MAX - *offset || flags != 0) 3536 return (EINVAL); 3537 if (vp->v_type != VREG) 3538 return (ENODEV); 3539 3540 switch (cmd) { 3541 case SPACECTL_DEALLOC: 3542 error = vn_deallocate_impl(vp, offset, length, flags, 0, 3543 active_cred, fp->f_cred); 3544 break; 3545 default: 3546 panic("vn_fspacectl: unknown cmd %d", cmd); 3547 } 3548 3549 return (error); 3550} 3551 |
|
3442static u_long vn_lock_pair_pause_cnt; 3443SYSCTL_ULONG(_debug, OID_AUTO, vn_lock_pair_pause, CTLFLAG_RD, 3444 &vn_lock_pair_pause_cnt, 0, 3445 "Count of vn_lock_pair deadlocks"); 3446 3447u_int vn_lock_pair_pause_max; 3448SYSCTL_UINT(_debug, OID_AUTO, vn_lock_pair_pause_max, CTLFLAG_RW, 3449 &vn_lock_pair_pause_max, 0, --- 93 unchanged lines hidden --- | 3552static u_long vn_lock_pair_pause_cnt; 3553SYSCTL_ULONG(_debug, OID_AUTO, vn_lock_pair_pause, CTLFLAG_RD, 3554 &vn_lock_pair_pause_cnt, 0, 3555 "Count of vn_lock_pair deadlocks"); 3556 3557u_int vn_lock_pair_pause_max; 3558SYSCTL_UINT(_debug, OID_AUTO, vn_lock_pair_pause_max, CTLFLAG_RW, 3559 &vn_lock_pair_pause_max, 0, --- 93 unchanged lines hidden --- |