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