Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/vfs_vnops.c
Show First 20 Lines • Show All 99 Lines • ▼ Show 20 Lines | |||||
static fo_rdwr_t vn_io_fault; | static fo_rdwr_t vn_io_fault; | ||||
static fo_truncate_t vn_truncate; | static fo_truncate_t vn_truncate; | ||||
static fo_ioctl_t vn_ioctl; | static fo_ioctl_t vn_ioctl; | ||||
static fo_poll_t vn_poll; | static fo_poll_t vn_poll; | ||||
static fo_kqfilter_t vn_kqfilter; | static fo_kqfilter_t vn_kqfilter; | ||||
static fo_stat_t vn_statfile; | static fo_stat_t vn_statfile; | ||||
static fo_close_t vn_closefile; | static fo_close_t vn_closefile; | ||||
static fo_mmap_t vn_mmap; | static fo_mmap_t vn_mmap; | ||||
static fo_fallocate_t vn_fallocate; | |||||
static fo_fspacectl_t vn_fspacectl; | static fo_fspacectl_t vn_fspacectl; | ||||
struct fileops vnops = { | struct fileops vnops = { | ||||
.fo_read = vn_io_fault, | .fo_read = vn_io_fault, | ||||
.fo_write = vn_io_fault, | .fo_write = vn_io_fault, | ||||
.fo_truncate = vn_truncate, | .fo_truncate = vn_truncate, | ||||
.fo_ioctl = vn_ioctl, | .fo_ioctl = vn_ioctl, | ||||
.fo_poll = vn_poll, | .fo_poll = vn_poll, | ||||
.fo_kqfilter = vn_kqfilter, | .fo_kqfilter = vn_kqfilter, | ||||
.fo_stat = vn_statfile, | .fo_stat = vn_statfile, | ||||
.fo_close = vn_closefile, | .fo_close = vn_closefile, | ||||
.fo_chmod = vn_chmod, | .fo_chmod = vn_chmod, | ||||
.fo_chown = vn_chown, | .fo_chown = vn_chown, | ||||
.fo_sendfile = vn_sendfile, | .fo_sendfile = vn_sendfile, | ||||
.fo_seek = vn_seek, | .fo_seek = vn_seek, | ||||
.fo_fill_kinfo = vn_fill_kinfo, | .fo_fill_kinfo = vn_fill_kinfo, | ||||
.fo_mmap = vn_mmap, | .fo_mmap = vn_mmap, | ||||
.fo_fallocate = vn_fallocate, | |||||
.fo_fspacectl = vn_fspacectl, | .fo_fspacectl = vn_fspacectl, | ||||
.fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE | .fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE | ||||
}; | }; | ||||
const u_int io_hold_cnt = 16; | const u_int io_hold_cnt = 16; | ||||
static int vn_io_fault_enable = 1; | static int vn_io_fault_enable = 1; | ||||
SYSCTL_INT(_debug, OID_AUTO, vn_io_fault_enable, CTLFLAG_RWTUN, | SYSCTL_INT(_debug, OID_AUTO, vn_io_fault_enable, CTLFLAG_RWTUN, | ||||
&vn_io_fault_enable, 0, "Enable vn_io_fault lock avoidance"); | &vn_io_fault_enable, 0, "Enable vn_io_fault lock avoidance"); | ||||
▲ Show 20 Lines • Show All 3,175 Lines • ▼ Show 20 Lines | #endif | ||||
} | } | ||||
out: | out: | ||||
*lenp = savlen - len; | *lenp = savlen - len; | ||||
free(dat, M_TEMP); | free(dat, M_TEMP); | ||||
return (error); | return (error); | ||||
} | } | ||||
static int | static int | ||||
vn_fallocate(struct file *fp, off_t offset, off_t len, struct thread *td) | vn_fallocate(struct file *fp, off_t offset, off_t len, int flags, | ||||
struct ucred *active_cred, struct thread *td) | |||||
{ | { | ||||
struct mount *mp; | struct mount *mp; | ||||
struct vnode *vp; | struct vnode *vp; | ||||
off_t olen, ooffset; | off_t olen, ooffset; | ||||
int error; | int error; | ||||
#ifdef AUDIT | #ifdef AUDIT | ||||
int audited_vnode1 = 0; | int audited_vnode1 = 0; | ||||
#endif | #endif | ||||
vp = fp->f_vnode; | vp = fp->f_vnode; | ||||
error = 0; | |||||
if (offset < 0 || len <= 0 || (flags & ~SPACECTL_F_SUPPORTED) != 0) | |||||
return (EINVAL); | |||||
if (vp->v_type != VREG) | if (vp->v_type != VREG) | ||||
return (ENODEV); | return (ENODEV); | ||||
len = omin(len, OFF_MAX - offset); | |||||
/* Allocating blocks may take a long time, so iterate. */ | /* Allocating blocks may take a long time, so iterate. */ | ||||
for (;;) { | for (;;) { | ||||
olen = len; | olen = len; | ||||
ooffset = offset; | ooffset = offset; | ||||
bwillwrite(); | bwillwrite(); | ||||
mp = NULL; | mp = NULL; | ||||
error = vn_start_write(vp, &mp, V_WAIT | PCATCH); | error = vn_start_write(vp, &mp, V_WAIT | PCATCH); | ||||
if (error != 0) | if (error != 0) | ||||
break; | break; | ||||
error = vn_lock(vp, LK_EXCLUSIVE); | error = vn_lock(vp, LK_EXCLUSIVE); | ||||
if (error != 0) { | if (error != 0) { | ||||
vn_finished_write(mp); | vn_finished_write(mp); | ||||
break; | break; | ||||
} | } | ||||
#ifdef AUDIT | #ifdef AUDIT | ||||
if (!audited_vnode1) { | if (!audited_vnode1) { | ||||
AUDIT_ARG_VNODE1(vp); | AUDIT_ARG_VNODE1(vp); | ||||
audited_vnode1 = 1; | audited_vnode1 = 1; | ||||
} | } | ||||
#endif | #endif | ||||
#ifdef MAC | #ifdef MAC | ||||
error = mac_vnode_check_write(td->td_ucred, fp->f_cred, vp); | error = mac_vnode_check_write(active_cred, fp->f_cred, vp); | ||||
if (error == 0) | if (error == 0) | ||||
#endif | #endif | ||||
error = VOP_ALLOCATE(vp, &offset, &len); | error = VOP_ALLOCATE(vp, &offset, &len, flags, | ||||
active_cred); | |||||
VOP_UNLOCK(vp); | VOP_UNLOCK(vp); | ||||
vn_finished_write(mp); | vn_finished_write(mp); | ||||
if (olen + ooffset != offset + len) { | |||||
panic("offset + len changed from %jx/%jx to %jx/%jx", | |||||
ooffset, olen, offset, len); | |||||
} | |||||
if (error != 0 || len == 0) | if (error != 0 || len == 0) | ||||
break; | break; | ||||
KASSERT(olen > len, ("Iteration did not make progress?")); | KASSERT(olen > len, ("Iteration did not make progress?")); | ||||
maybe_yield(); | maybe_yield(); | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 96 Lines • ▼ Show 20 Lines | |||||
vn_fspacectl(struct file *fp, int cmd, off_t offset, off_t len, int flags, | vn_fspacectl(struct file *fp, int cmd, off_t offset, off_t len, int flags, | ||||
struct ucred *active_cred, struct thread *td) | struct ucred *active_cred, struct thread *td) | ||||
{ | { | ||||
int error; | int error; | ||||
struct vnode *vp; | struct vnode *vp; | ||||
vp = fp->f_vnode; | vp = fp->f_vnode; | ||||
if (cmd != SPACECTL_DEALLOC) | if (cmd != SPACECTL_ALLOC && cmd != SPACECTL_DEALLOC) | ||||
return (EINVAL); | return (EINVAL); | ||||
switch (cmd) { | switch (cmd) { | ||||
case SPACECTL_ALLOC: | |||||
error = vn_fallocate(fp, offset, len, flags, active_cred, td); | |||||
break; | |||||
case SPACECTL_DEALLOC: | case SPACECTL_DEALLOC: | ||||
error = vn_deallocate_impl(vp, offset, len, flags, 0, true, | error = vn_deallocate_impl(vp, offset, len, flags, 0, true, | ||||
active_cred, fp->f_cred, td); | active_cred, fp->f_cred, td); | ||||
break; | break; | ||||
default: | default: | ||||
panic("vn_fspacectl: unknown cmd %d", cmd); | panic("vn_fspacectl: unknown cmd %d", cmd); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 95 Lines • Show Last 20 Lines |