summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/bus_if.m13
-rw-r--r--sys/kern/imgact_elf.c8
-rw-r--r--sys/kern/init_sysent.c10
-rw-r--r--sys/kern/kern_descrip.c61
-rw-r--r--sys/kern/kern_event.c14
-rw-r--r--sys/kern/kern_exit.c22
-rw-r--r--sys/kern/kern_intr.c5
-rw-r--r--sys/kern/kern_proc.c22
-rw-r--r--sys/kern/kern_prot.c12
-rw-r--r--sys/kern/kern_racct.c84
-rw-r--r--sys/kern/kern_sig.c29
-rw-r--r--sys/kern/kern_timeout.c14
-rw-r--r--sys/kern/subr_bus.c31
-rw-r--r--sys/kern/subr_witness.c39
-rw-r--r--sys/kern/sys_process.c2
-rw-r--r--sys/kern/syscalls.c2
-rw-r--r--sys/kern/syscalls.master8
-rw-r--r--sys/kern/tty.c43
-rw-r--r--sys/kern/uipc_syscalls.c491
-rw-r--r--sys/kern/vfs_bio.c9
-rw-r--r--sys/kern/vfs_vnops.c26
21 files changed, 251 insertions, 694 deletions
diff --git a/sys/kern/bus_if.m b/sys/kern/bus_if.m
index ccc854c..cce997c 100644
--- a/sys/kern/bus_if.m
+++ b/sys/kern/bus_if.m
@@ -692,3 +692,16 @@ METHOD int resume_child {
device_t _dev;
device_t _child;
} DEFAULT bus_generic_resume_child;
+
+/**
+ * @brief Get the VM domain handle for the given bus and child.
+ *
+ * @param _dev the bus device
+ * @param _child the child device
+ * @param _domain a pointer to the bus's domain handle identifier
+ */
+METHOD int get_domain {
+ device_t _dev;
+ device_t _child;
+ int *_domain;
+} DEFAULT bus_generic_get_domain;
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index 634a50c..e3494f6 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -1112,8 +1112,8 @@ core_output(struct vnode *vp, void *base, size_t len, off_t offset,
#endif
} else {
error = vn_rdwr_inchunks(UIO_WRITE, vp, base, len, offset,
- UIO_USERSPACE, IO_UNIT | IO_DIRECT, active_cred, file_cred,
- NULL, td);
+ UIO_USERSPACE, IO_UNIT | IO_DIRECT | IO_RANGELOCKED,
+ active_cred, file_cred, NULL, td);
}
return (error);
}
@@ -1160,8 +1160,8 @@ sbuf_drain_core_output(void *arg, const char *data, int len)
#endif
error = vn_rdwr_inchunks(UIO_WRITE, p->vp,
__DECONST(void *, data), len, p->offset, UIO_SYSSPACE,
- IO_UNIT | IO_DIRECT, p->active_cred, p->file_cred, NULL,
- p->td);
+ IO_UNIT | IO_DIRECT | IO_RANGELOCKED, p->active_cred,
+ p->file_cred, NULL, p->td);
if (locked)
PROC_LOCK(p->td->td_proc);
if (error != 0)
diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c
index 0e6e0f1..3decfd41 100644
--- a/sys/kern/init_sysent.c
+++ b/sys/kern/init_sysent.c
@@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: head/sys/kern/syscalls.master 263318 2014-03-18 21:32:03Z attilio
+ * created from FreeBSD: head/sys/kern/syscalls.master 272823 2014-10-09 15:16:52Z marcel
*/
#include "opt_compat.h"
@@ -505,10 +505,10 @@ struct sysent sysent[] = {
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 468 = nosys */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 469 = __getpath_fromfd */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 470 = __getpath_fromaddr */
- { AS(sctp_peeloff_args), (sy_call_t *)sys_sctp_peeloff, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 471 = sctp_peeloff */
- { AS(sctp_generic_sendmsg_args), (sy_call_t *)sys_sctp_generic_sendmsg, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 472 = sctp_generic_sendmsg */
- { AS(sctp_generic_sendmsg_iov_args), (sy_call_t *)sys_sctp_generic_sendmsg_iov, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 473 = sctp_generic_sendmsg_iov */
- { AS(sctp_generic_recvmsg_args), (sy_call_t *)sys_sctp_generic_recvmsg, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 474 = sctp_generic_recvmsg */
+ { AS(sctp_peeloff_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_ABSENT }, /* 471 = sctp_peeloff */
+ { AS(sctp_generic_sendmsg_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_ABSENT }, /* 472 = sctp_generic_sendmsg */
+ { AS(sctp_generic_sendmsg_iov_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_ABSENT }, /* 473 = sctp_generic_sendmsg_iov */
+ { AS(sctp_generic_recvmsg_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_ABSENT }, /* 474 = sctp_generic_recvmsg */
{ AS(pread_args), (sy_call_t *)sys_pread, AUE_PREAD, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 475 = pread */
{ AS(pwrite_args), (sy_call_t *)sys_pwrite, AUE_PWRITE, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 476 = pwrite */
{ AS(mmap_args), (sy_call_t *)sys_mmap, AUE_MMAP, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 477 = mmap */
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index c48378c..c51a876 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -288,11 +288,18 @@ _fdfree(struct filedesc *fdp, int fd, int last)
struct filedescent *fde;
fde = &fdp->fd_ofiles[fd];
+#ifdef CAPABILITIES
+ if (!last)
+ seq_write_begin(&fde->fde_seq);
+#endif
filecaps_free(&fde->fde_caps);
if (last)
return;
- bzero(fde, sizeof(*fde));
+ bzero(fde, fde_change_size);
fdunused(fdp, fd);
+#ifdef CAPABILITIES
+ seq_write_end(&fde->fde_seq);
+#endif
}
static inline void
@@ -883,13 +890,19 @@ do_dup(struct thread *td, int flags, int old, int new,
/*
* Duplicate the source descriptor.
*/
+#ifdef CAPABILITIES
+ seq_write_begin(&newfde->fde_seq);
+#endif
filecaps_free(&newfde->fde_caps);
- *newfde = *oldfde;
+ memcpy(newfde, oldfde, fde_change_size);
filecaps_copy(&oldfde->fde_caps, &newfde->fde_caps);
if ((flags & DUP_CLOEXEC) != 0)
newfde->fde_flags = oldfde->fde_flags | UF_EXCLOSE;
else
newfde->fde_flags = oldfde->fde_flags & ~UF_EXCLOSE;
+#ifdef CAPABILITIES
+ seq_write_end(&newfde->fde_seq);
+#endif
*retval = new;
if (delfp != NULL) {
@@ -1756,6 +1769,9 @@ finstall(struct thread *td, struct file *fp, int *fd, int flags,
}
fhold(fp);
fde = &fdp->fd_ofiles[*fd];
+#ifdef CAPABILITIES
+ seq_write_begin(&fde->fde_seq);
+#endif
fde->fde_file = fp;
if ((flags & O_CLOEXEC) != 0)
fde->fde_flags |= UF_EXCLOSE;
@@ -1763,6 +1779,9 @@ finstall(struct thread *td, struct file *fp, int *fd, int flags,
filecaps_move(fcaps, &fde->fde_caps);
else
filecaps_fill(&fde->fde_caps);
+#ifdef CAPABILITIES
+ seq_write_end(&fde->fde_seq);
+#endif
FILEDESC_XUNLOCK(fdp);
return (0);
}
@@ -2294,6 +2313,7 @@ fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
struct file *fp;
u_int count;
#ifdef CAPABILITIES
+ seq_t seq;
cap_rights_t haverights;
int error;
#endif
@@ -2314,7 +2334,12 @@ fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
*/
for (;;) {
#ifdef CAPABILITIES
+ seq = seq_read(fd_seq(fdp, fd));
fde = fdp->fd_ofiles[fd];
+ if (!seq_consistent(fd_seq(fdp, fd), seq)) {
+ cpu_spinwait();
+ continue;
+ }
fp = fde.fde_file;
#else
fp = fdp->fd_ofiles[fd].fde_file;
@@ -2343,7 +2368,11 @@ fget_unlocked(struct filedesc *fdp, int fd, cap_rights_t *needrightsp,
*/
if (atomic_cmpset_acq_int(&fp->f_count, count, count + 1) != 1)
continue;
+#ifdef CAPABILITIES
+ if (seq_consistent_nomb(fd_seq(fdp, fd), seq))
+#else
if (fp == fdp->fd_ofiles[fd].fde_file)
+#endif
break;
fdrop(fp, curthread);
}
@@ -2700,6 +2729,7 @@ int
dupfdopen(struct thread *td, struct filedesc *fdp, int dfd, int mode,
int openerror, int *indxp)
{
+ struct filedescent *newfde, *oldfde;
struct file *fp;
int error, indx;
@@ -2743,17 +2773,32 @@ dupfdopen(struct thread *td, struct filedesc *fdp, int dfd, int mode,
return (EACCES);
}
fhold(fp);
- fdp->fd_ofiles[indx] = fdp->fd_ofiles[dfd];
- filecaps_copy(&fdp->fd_ofiles[dfd].fde_caps,
- &fdp->fd_ofiles[indx].fde_caps);
+ newfde = &fdp->fd_ofiles[indx];
+ oldfde = &fdp->fd_ofiles[dfd];
+#ifdef CAPABILITIES
+ seq_write_begin(&newfde->fde_seq);
+#endif
+ memcpy(newfde, oldfde, fde_change_size);
+ filecaps_copy(&oldfde->fde_caps, &newfde->fde_caps);
+#ifdef CAPABILITIES
+ seq_write_end(&newfde->fde_seq);
+#endif
break;
case ENXIO:
/*
* Steal away the file pointer from dfd and stuff it into indx.
*/
- fdp->fd_ofiles[indx] = fdp->fd_ofiles[dfd];
- bzero(&fdp->fd_ofiles[dfd], sizeof(fdp->fd_ofiles[dfd]));
+ newfde = &fdp->fd_ofiles[indx];
+ oldfde = &fdp->fd_ofiles[dfd];
+#ifdef CAPABILITIES
+ seq_write_begin(&newfde->fde_seq);
+#endif
+ memcpy(newfde, oldfde, fde_change_size);
+ bzero(oldfde, fde_change_size);
fdunused(fdp, dfd);
+#ifdef CAPABILITIES
+ seq_write_end(&newfde->fde_seq);
+#endif
break;
}
FILEDESC_XUNLOCK(fdp);
@@ -3052,7 +3097,7 @@ export_kinfo_to_sb(struct export_fd_buf *efbuf)
}
efbuf->remainder -= kif->kf_structsize;
}
- return (sbuf_bcat(efbuf->sb, kif, kif->kf_structsize));
+ return (sbuf_bcat(efbuf->sb, kif, kif->kf_structsize) == 0 ? 0 : ENOMEM);
}
static int
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index 7488652..55bffe7 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -569,9 +569,10 @@ filt_timerexpire(void *knx)
if ((kn->kn_flags & EV_ONESHOT) != EV_ONESHOT) {
calloutp = (struct callout *)kn->kn_hook;
- callout_reset_sbt_on(calloutp,
- timer2sbintime(kn->kn_sdata, kn->kn_sfflags), 0,
- filt_timerexpire, kn, PCPU_GET(cpuid), 0);
+ *kn->kn_ptr.p_nexttime += timer2sbintime(kn->kn_sdata,
+ kn->kn_sfflags);
+ callout_reset_sbt_on(calloutp, *kn->kn_ptr.p_nexttime, 0,
+ filt_timerexpire, kn, PCPU_GET(cpuid), C_ABSOLUTE);
}
}
@@ -607,11 +608,13 @@ filt_timerattach(struct knote *kn)
kn->kn_flags |= EV_CLEAR; /* automatically set */
kn->kn_status &= ~KN_DETACHED; /* knlist_add clears it */
+ kn->kn_ptr.p_nexttime = malloc(sizeof(sbintime_t), M_KQUEUE, M_WAITOK);
calloutp = malloc(sizeof(*calloutp), M_KQUEUE, M_WAITOK);
callout_init(calloutp, CALLOUT_MPSAFE);
kn->kn_hook = calloutp;
- callout_reset_sbt_on(calloutp, to, 0,
- filt_timerexpire, kn, PCPU_GET(cpuid), 0);
+ *kn->kn_ptr.p_nexttime = to + sbinuptime();
+ callout_reset_sbt_on(calloutp, *kn->kn_ptr.p_nexttime, 0,
+ filt_timerexpire, kn, PCPU_GET(cpuid), C_ABSOLUTE);
return (0);
}
@@ -625,6 +628,7 @@ filt_timerdetach(struct knote *kn)
calloutp = (struct callout *)kn->kn_hook;
callout_drain(calloutp);
free(calloutp, M_KQUEUE);
+ free(kn->kn_ptr.p_nexttime, M_KQUEUE);
old = atomic_fetch_sub_explicit(&kq_ncallouts, 1, memory_order_relaxed);
KASSERT(old > 0, ("Number of callouts cannot become negative"));
kn->kn_status |= KN_DETACHED; /* knlist_remove sets it */
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 1dbb997..1e4c095 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -265,8 +265,8 @@ exit1(struct thread *td, int rv)
AUDIT_SYSCALL_EXIT(0, td);
#endif
- /* Are we a task leader? */
- if (p == p->p_leader) {
+ /* Are we a task leader with peers? */
+ if (p->p_peers != NULL && p == p->p_leader) {
mtx_lock(&ppeers_lock);
q = p->p_peers;
while (q != NULL) {
@@ -337,15 +337,17 @@ exit1(struct thread *td, int rv)
/*
* Remove ourself from our leader's peer list and wake our leader.
*/
- mtx_lock(&ppeers_lock);
- if (p->p_leader->p_peers) {
- q = p->p_leader;
- while (q->p_peers != p)
- q = q->p_peers;
- q->p_peers = p->p_peers;
- wakeup(p->p_leader);
+ if (p->p_leader->p_peers != NULL) {
+ mtx_lock(&ppeers_lock);
+ if (p->p_leader->p_peers != NULL) {
+ q = p->p_leader;
+ while (q->p_peers != p)
+ q = q->p_peers;
+ q->p_peers = p->p_peers;
+ wakeup(p->p_leader);
+ }
+ mtx_unlock(&ppeers_lock);
}
- mtx_unlock(&ppeers_lock);
vmspace_exit(td);
diff --git a/sys/kern/kern_intr.c b/sys/kern/kern_intr.c
index 6e9a4e8..d6de611 100644
--- a/sys/kern/kern_intr.c
+++ b/sys/kern/kern_intr.c
@@ -28,6 +28,7 @@
__FBSDID("$FreeBSD$");
#include "opt_ddb.h"
+#include "opt_kstack_usage_prof.h"
#include <sys/param.h>
#include <sys/bus.h>
@@ -1396,6 +1397,10 @@ intr_event_handle(struct intr_event *ie, struct trapframe *frame)
td = curthread;
+#ifdef KSTACK_USAGE_PROF
+ intr_prof_stack_use(td, frame);
+#endif
+
/* An interrupt with no event or handlers is a stray interrupt. */
if (ie == NULL || TAILQ_EMPTY(&ie->ie_handlers))
return (EINVAL);
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index 96510c9..41cd304 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -1208,21 +1208,25 @@ kern_proc_out(struct proc *p, struct sbuf *sb, int flags)
#ifdef COMPAT_FREEBSD32
if ((flags & KERN_PROC_MASK32) != 0) {
freebsd32_kinfo_proc_out(&ki, &ki32);
- error = sbuf_bcat(sb, &ki32, sizeof(ki32));
+ if (sbuf_bcat(sb, &ki32, sizeof(ki32)) != 0)
+ error = ENOMEM;
} else
#endif
- error = sbuf_bcat(sb, &ki, sizeof(ki));
+ if (sbuf_bcat(sb, &ki, sizeof(ki)) != 0)
+ error = ENOMEM;
} else {
FOREACH_THREAD_IN_PROC(p, td) {
fill_kinfo_thread(td, &ki, 1);
#ifdef COMPAT_FREEBSD32
if ((flags & KERN_PROC_MASK32) != 0) {
freebsd32_kinfo_proc_out(&ki, &ki32);
- error = sbuf_bcat(sb, &ki32, sizeof(ki32));
+ if (sbuf_bcat(sb, &ki32, sizeof(ki32)) != 0)
+ error = ENOMEM;
} else
#endif
- error = sbuf_bcat(sb, &ki, sizeof(ki));
- if (error)
+ if (sbuf_bcat(sb, &ki, sizeof(ki)) != 0)
+ error = ENOMEM;
+ if (error != 0)
break;
}
}
@@ -1777,7 +1781,8 @@ proc_getauxv(struct thread *td, struct proc *p, struct sbuf *sb)
else
#endif
size = vsize * sizeof(Elf_Auxinfo);
- error = sbuf_bcat(sb, auxv, size);
+ if (sbuf_bcat(sb, auxv, size) != 0)
+ error = ENOMEM;
free(auxv, M_TEMP);
}
return (error);
@@ -2363,9 +2368,10 @@ kern_proc_vmmap_out(struct proc *p, struct sbuf *sb)
strlen(kve->kve_path) + 1;
kve->kve_structsize = roundup(kve->kve_structsize,
sizeof(uint64_t));
- error = sbuf_bcat(sb, kve, kve->kve_structsize);
+ if (sbuf_bcat(sb, kve, kve->kve_structsize) != 0)
+ error = ENOMEM;
vm_map_lock_read(map);
- if (error)
+ if (error != 0)
break;
if (last_timestamp != map->timestamp) {
vm_map_lookup_entry(map, addr - 1, &tmp_entry);
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index 7552363..fd2b7f4 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -1884,23 +1884,13 @@ crfree(struct ucred *cr)
}
/*
- * Check to see if this ucred is shared.
- */
-int
-crshared(struct ucred *cr)
-{
-
- return (cr->cr_ref > 1);
-}
-
-/*
* Copy a ucred's contents from a template. Does not block.
*/
void
crcopy(struct ucred *dest, struct ucred *src)
{
- KASSERT(crshared(dest) == 0, ("crcopy of shared ucred"));
+ KASSERT(dest->cr_ref == 1, ("crcopy of shared ucred"));
bcopy(&src->cr_startcopy, &dest->cr_startcopy,
(unsigned)((caddr_t)&src->cr_endcopy -
(caddr_t)&src->cr_startcopy));
diff --git a/sys/kern/kern_racct.c b/sys/kern/kern_racct.c
index 26ebc4e..84fa312 100644
--- a/sys/kern/kern_racct.c
+++ b/sys/kern/kern_racct.c
@@ -1203,88 +1203,4 @@ racct_init(void)
}
SYSINIT(racct, SI_SUB_RACCT, SI_ORDER_FIRST, racct_init, NULL);
-#else /* !RACCT */
-
-int
-racct_add(struct proc *p, int resource, uint64_t amount)
-{
-
- return (0);
-}
-
-void
-racct_add_cred(struct ucred *cred, int resource, uint64_t amount)
-{
-}
-
-void
-racct_add_force(struct proc *p, int resource, uint64_t amount)
-{
-
- return;
-}
-
-int
-racct_set(struct proc *p, int resource, uint64_t amount)
-{
-
- return (0);
-}
-
-void
-racct_set_force(struct proc *p, int resource, uint64_t amount)
-{
-}
-
-void
-racct_sub(struct proc *p, int resource, uint64_t amount)
-{
-}
-
-void
-racct_sub_cred(struct ucred *cred, int resource, uint64_t amount)
-{
-}
-
-uint64_t
-racct_get_limit(struct proc *p, int resource)
-{
-
- return (UINT64_MAX);
-}
-
-uint64_t
-racct_get_available(struct proc *p, int resource)
-{
-
- return (UINT64_MAX);
-}
-
-void
-racct_create(struct racct **racctp)
-{
-}
-
-void
-racct_destroy(struct racct **racctp)
-{
-}
-
-int
-racct_proc_fork(struct proc *parent, struct proc *child)
-{
-
- return (0);
-}
-
-void
-racct_proc_fork_done(struct proc *child)
-{
-}
-
-void
-racct_proc_exit(struct proc *p)
-{
-}
-
#endif /* !RACCT */
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index 1bb042f..5cdc2ce 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -3214,8 +3214,8 @@ coredump(struct thread *td)
struct flock lf;
struct vattr vattr;
int error, error1, locked;
- struct mount *mp;
char *name; /* name of corefile */
+ void *rl_cookie;
off_t limit;
int compress;
@@ -3248,39 +3248,33 @@ coredump(struct thread *td)
}
PROC_UNLOCK(p);
-restart:
error = corefile_open(p->p_comm, cred->cr_uid, p->p_pid, td, compress,
&vp, &name);
if (error != 0)
return (error);
- /* Don't dump to non-regular files or files with links. */
+ /*
+ * Don't dump to non-regular files or files with links.
+ * Do not dump into system files.
+ */
if (vp->v_type != VREG || VOP_GETATTR(vp, &vattr, cred) != 0 ||
- vattr.va_nlink != 1) {
+ vattr.va_nlink != 1 || (vp->v_vflag & VV_SYSTEM) != 0) {
VOP_UNLOCK(vp, 0);
error = EFAULT;
goto close;
}
VOP_UNLOCK(vp, 0);
+
+ /* Postpone other writers, including core dumps of other processes. */
+ rl_cookie = vn_rangelock_wlock(vp, 0, OFF_MAX);
+
lf.l_whence = SEEK_SET;
lf.l_start = 0;
lf.l_len = 0;
lf.l_type = F_WRLCK;
locked = (VOP_ADVLOCK(vp, (caddr_t)p, F_SETLK, &lf, F_FLOCK) == 0);
- if (vn_start_write(vp, &mp, V_NOWAIT) != 0) {
- lf.l_type = F_UNLCK;
- if (locked)
- VOP_ADVLOCK(vp, (caddr_t)p, F_UNLCK, &lf, F_FLOCK);
- if ((error = vn_close(vp, FWRITE, cred, td)) != 0)
- goto out;
- if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0)
- goto out;
- free(name, M_TEMP);
- goto restart;
- }
-
VATTR_NULL(&vattr);
vattr.va_size = 0;
if (set_core_nodump_flag)
@@ -3288,7 +3282,6 @@ restart:
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
VOP_SETATTR(vp, &vattr, cred);
VOP_UNLOCK(vp, 0);
- vn_finished_write(mp);
PROC_LOCK(p);
p->p_acflag |= ACORE;
PROC_UNLOCK(p);
@@ -3304,11 +3297,11 @@ restart:
lf.l_type = F_UNLCK;
VOP_ADVLOCK(vp, (caddr_t)p, F_UNLCK, &lf, F_FLOCK);
}
+ vn_rangelock_unlock(vp, rl_cookie);
close:
error1 = vn_close(vp, FWRITE, cred, td);
if (error == 0)
error = error1;
-out:
#ifdef AUDIT
audit_proc_coredump(td, name, error);
#endif
diff --git a/sys/kern/kern_timeout.c b/sys/kern/kern_timeout.c
index b503633..13822fd 100644
--- a/sys/kern/kern_timeout.c
+++ b/sys/kern/kern_timeout.c
@@ -163,6 +163,7 @@ struct callout_cpu {
sbintime_t cc_lastscan;
void *cc_cookie;
u_int cc_bucket;
+ char cc_ktr_event_name[20];
};
#define cc_exec_curr cc_exec_entity[0].cc_curr
@@ -201,7 +202,7 @@ struct callout_cpu cc_cpu;
static int timeout_cpu;
-static void callout_cpu_init(struct callout_cpu *cc);
+static void callout_cpu_init(struct callout_cpu *cc, int cpu);
static void softclock_call_cc(struct callout *c, struct callout_cpu *cc,
#ifdef CALLOUT_PROFILING
int *mpcalls, int *lockcalls, int *gcalls,
@@ -302,7 +303,7 @@ callout_callwheel_init(void *dummy)
cc = CC_CPU(timeout_cpu);
cc->cc_callout = malloc(ncallout * sizeof(struct callout),
M_CALLOUT, M_WAITOK);
- callout_cpu_init(cc);
+ callout_cpu_init(cc, timeout_cpu);
}
SYSINIT(callwheel_init, SI_SUB_CPU, SI_ORDER_ANY, callout_callwheel_init, NULL);
@@ -310,7 +311,7 @@ SYSINIT(callwheel_init, SI_SUB_CPU, SI_ORDER_ANY, callout_callwheel_init, NULL);
* Initialize the per-cpu callout structures.
*/
static void
-callout_cpu_init(struct callout_cpu *cc)
+callout_cpu_init(struct callout_cpu *cc, int cpu)
{
struct callout *c;
int i;
@@ -325,6 +326,8 @@ callout_cpu_init(struct callout_cpu *cc)
cc->cc_firstevent = SBT_MAX;
for (i = 0; i < 2; i++)
cc_cce_cleanup(cc, i);
+ snprintf(cc->cc_ktr_event_name, sizeof(cc->cc_ktr_event_name),
+ "callwheel cpu %d", cpu);
if (cc->cc_callout == NULL) /* Only cpu0 handles timeout(9) */
return;
for (i = 0; i < ncallout; i++) {
@@ -396,7 +399,7 @@ start_softclock(void *dummy)
continue;
cc = CC_CPU(cpu);
cc->cc_callout = NULL; /* Only cpu0 handles timeout(9). */
- callout_cpu_init(cc);
+ callout_cpu_init(cc, cpu);
snprintf(name, sizeof(name), "clock (%d)", cpu);
ie = NULL;
if (swi_add(&ie, name, softclock, cc, SWI_CLOCK,
@@ -711,6 +714,8 @@ softclock_call_cc(struct callout *c, struct callout_cpu *cc,
CTR3(KTR_CALLOUT, "callout %p func %p arg %p",
c, c_func, c_arg);
}
+ KTR_STATE3(KTR_SCHED, "callout", cc->cc_ktr_event_name, "running",
+ "func:%p", c_func, "arg:%p", c_arg, "direct:%d", direct);
#if defined(DIAGNOSTIC) || defined(CALLOUT_PROFILING)
sbt1 = sbinuptime();
#endif
@@ -733,6 +738,7 @@ softclock_call_cc(struct callout *c, struct callout_cpu *cc,
lastfunc = c_func;
}
#endif
+ KTR_STATE0(KTR_SCHED, "callout", cc->cc_ktr_event_name, "idle");
CTR1(KTR_CALLOUT, "callout %p finished", c);
if ((c_flags & CALLOUT_RETURNUNLOCKED) == 0)
class->lc_unlock(c_lock);
diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c
index 974c540..31ad45e 100644
--- a/sys/kern/subr_bus.c
+++ b/sys/kern/subr_bus.c
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
#include <sys/uio.h>
#include <sys/bus.h>
#include <sys/interrupt.h>
+#include <sys/cpuset.h>
#include <net/vnet.h>
@@ -3754,6 +3755,25 @@ bus_print_child_footer(device_t dev, device_t child)
/**
* @brief Helper function for implementing BUS_PRINT_CHILD().
*
+ * This function prints out the VM domain for the given device.
+ *
+ * @returns the number of characters printed
+ */
+int
+bus_print_child_domain(device_t dev, device_t child)
+{
+ int domain;
+
+ /* No domain? Don't print anything */
+ if (BUS_GET_DOMAIN(dev, child, &domain) != 0)
+ return (0);
+
+ return (printf(" numa-domain %d", domain));
+}
+
+/**
+ * @brief Helper function for implementing BUS_PRINT_CHILD().
+ *
* This function simply calls bus_print_child_header() followed by
* bus_print_child_footer().
*
@@ -3765,6 +3785,7 @@ bus_generic_print_child(device_t dev, device_t child)
int retval = 0;
retval += bus_print_child_header(dev, child);
+ retval += bus_print_child_domain(dev, child);
retval += bus_print_child_footer(dev, child);
return (retval);
@@ -4179,6 +4200,16 @@ bus_generic_child_present(device_t dev, device_t child)
return (BUS_CHILD_PRESENT(device_get_parent(dev), dev));
}
+int
+bus_generic_get_domain(device_t dev, device_t child, int *domain)
+{
+
+ if (dev->parent)
+ return (BUS_GET_DOMAIN(dev->parent, dev, domain));
+
+ return (ENOENT);
+}
+
/*
* Some convenience functions to make it easier for drivers to use the
* resource-management functions. All these really do is hide the
diff --git a/sys/kern/subr_witness.c b/sys/kern/subr_witness.c
index 309f2e2..1bbb3dc 100644
--- a/sys/kern/subr_witness.c
+++ b/sys/kern/subr_witness.c
@@ -135,7 +135,6 @@ __FBSDID("$FreeBSD$");
#ifndef WITNESS_COUNT
#define WITNESS_COUNT 1536
#endif
-#define WITNESS_CHILDCOUNT (WITNESS_COUNT * 4)
#define WITNESS_HASH_SIZE 251 /* Prime, gives load factor < 2 */
#define WITNESS_PENDLIST (1024 + MAXCPU)
@@ -155,7 +154,6 @@ __FBSDID("$FreeBSD$");
#define MAX_W_NAME 64
-#define BADSTACK_SBUF_SIZE (256 * WITNESS_COUNT)
#define FULLGRAPH_SBUF_SIZE 512
/*
@@ -184,7 +182,7 @@ __FBSDID("$FreeBSD$");
#define WITNESS_ATOD(x) (((x) & WITNESS_RELATED_MASK) << 2)
#define WITNESS_INDEX_ASSERT(i) \
- MPASS((i) > 0 && (i) <= w_max_used_index && (i) < WITNESS_COUNT)
+ MPASS((i) > 0 && (i) <= w_max_used_index && (i) < witness_count)
static MALLOC_DEFINE(M_WITNESS, "Witness", "Witness");
@@ -416,6 +414,12 @@ int witness_skipspin = 0;
#endif
SYSCTL_INT(_debug_witness, OID_AUTO, skipspin, CTLFLAG_RDTUN, &witness_skipspin, 0, "");
+int badstack_sbuf_size;
+
+int witness_count = WITNESS_COUNT;
+SYSCTL_INT(_debug_witness, OID_AUTO, witness_count, CTLFLAG_RDTUN,
+ &witness_count, 0, "");
+
/*
* Call this to print out the relations between locks.
*/
@@ -450,7 +454,7 @@ SYSCTL_INT(_debug_witness, OID_AUTO, sleep_cnt, CTLFLAG_RD, &w_sleep_cnt, 0,
"");
static struct witness *w_data;
-static uint8_t w_rmatrix[WITNESS_COUNT+1][WITNESS_COUNT+1];
+static uint8_t **w_rmatrix;
static struct lock_list_entry w_locklistdata[LOCK_CHILDCOUNT];
static struct witness_hash w_hash; /* The witness hash table. */
@@ -726,8 +730,17 @@ witness_initialize(void *dummy __unused)
struct witness *w, *w1;
int i;
- w_data = malloc(sizeof (struct witness) * WITNESS_COUNT, M_WITNESS,
- M_NOWAIT | M_ZERO);
+ w_data = malloc(sizeof (struct witness) * witness_count, M_WITNESS,
+ M_WAITOK | M_ZERO);
+
+ w_rmatrix = malloc(sizeof(*w_rmatrix) * (witness_count + 1),
+ M_WITNESS, M_WAITOK | M_ZERO);
+
+ for (i = 0; i < witness_count + 1; i++) {
+ w_rmatrix[i] = malloc(sizeof(*w_rmatrix[i]) *
+ (witness_count + 1), M_WITNESS, M_WAITOK | M_ZERO);
+ }
+ badstack_sbuf_size = witness_count * 256;
/*
* We have to release Giant before initializing its witness
@@ -739,7 +752,7 @@ witness_initialize(void *dummy __unused)
CTR1(KTR_WITNESS, "%s: initializing witness", __func__);
mtx_init(&w_mtx, "witness lock", NULL, MTX_SPIN | MTX_QUIET |
MTX_NOWITNESS | MTX_NOPROFILE);
- for (i = WITNESS_COUNT - 1; i >= 0; i--) {
+ for (i = witness_count - 1; i >= 0; i--) {
w = &w_data[i];
memset(w, 0, sizeof(*w));
w_data[i].w_index = i; /* Witness index never changes. */
@@ -752,8 +765,10 @@ witness_initialize(void *dummy __unused)
STAILQ_REMOVE_HEAD(&w_free, w_list);
w_free_cnt--;
- memset(w_rmatrix, 0,
- (sizeof(**w_rmatrix) * (WITNESS_COUNT+1) * (WITNESS_COUNT+1)));
+ for (i = 0; i < witness_count; i++) {
+ memset(w_rmatrix[i], 0, sizeof(*w_rmatrix[i]) *
+ (witness_count + 1));
+ }
for (i = 0; i < LOCK_CHILDCOUNT; i++)
witness_lock_list_free(&w_locklistdata[i]);
@@ -1196,7 +1211,7 @@ witness_checkorder(struct lock_object *lock, int flags, const char *file,
for (j = 0, lle = lock_list; lle != NULL; lle = lle->ll_next) {
for (i = lle->ll_count - 1; i >= 0; i--, j++) {
- MPASS(j < WITNESS_COUNT);
+ MPASS(j < witness_count);
lock1 = &lle->ll_children[i];
/*
@@ -2057,7 +2072,7 @@ witness_get(void)
w_free_cnt--;
index = w->w_index;
MPASS(index > 0 && index == w_max_used_index+1 &&
- index < WITNESS_COUNT);
+ index < witness_count);
bzero(w, sizeof(*w));
w->w_index = index;
if (index > w_max_used_index)
@@ -2482,7 +2497,7 @@ sysctl_debug_witness_badstacks(SYSCTL_HANDLER_ARGS)
return (error);
}
error = 0;
- sb = sbuf_new(NULL, NULL, BADSTACK_SBUF_SIZE, SBUF_AUTOEXTEND);
+ sb = sbuf_new(NULL, NULL, badstack_sbuf_size, SBUF_AUTOEXTEND);
if (sb == NULL)
return (ENOMEM);
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
index b30e12a..d97b583 100644
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -1240,7 +1240,7 @@ protect_setchild(struct thread *td, struct proc *p, int flags)
{
PROC_LOCK_ASSERT(p, MA_OWNED);
- if (p->p_flag & P_SYSTEM || p_cansee(td, p) != 0)
+ if (p->p_flag & P_SYSTEM || p_cansched(td, p) != 0)
return (0);
if (flags & PPROT_SET) {
p->p_flag |= P_PROTECTED;
diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c
index d9f8388..276c34a 100644
--- a/sys/kern/syscalls.c
+++ b/sys/kern/syscalls.c
@@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
- * created from FreeBSD: head/sys/kern/syscalls.master 263318 2014-03-18 21:32:03Z attilio
+ * created from FreeBSD: head/sys/kern/syscalls.master 272823 2014-10-09 15:16:52Z marcel
*/
const char *syscallnames[] = {
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
index 71e6273..35c05f0 100644
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -837,14 +837,14 @@
468 AUE_NULL UNIMPL nosys
469 AUE_NULL UNIMPL __getpath_fromfd
470 AUE_NULL UNIMPL __getpath_fromaddr
-471 AUE_NULL STD { int sctp_peeloff(int sd, uint32_t name); }
-472 AUE_NULL STD { int sctp_generic_sendmsg(int sd, caddr_t msg, int mlen, \
+471 AUE_NULL NOSTD { int sctp_peeloff(int sd, uint32_t name); }
+472 AUE_NULL NOSTD { int sctp_generic_sendmsg(int sd, caddr_t msg, int mlen, \
caddr_t to, __socklen_t tolen, \
struct sctp_sndrcvinfo *sinfo, int flags); }
-473 AUE_NULL STD { int sctp_generic_sendmsg_iov(int sd, struct iovec *iov, int iovlen, \
+473 AUE_NULL NOSTD { int sctp_generic_sendmsg_iov(int sd, struct iovec *iov, int iovlen, \
caddr_t to, __socklen_t tolen, \
struct sctp_sndrcvinfo *sinfo, int flags); }
-474 AUE_NULL STD { int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, \
+474 AUE_NULL NOSTD { int sctp_generic_recvmsg(int sd, struct iovec *iov, int iovlen, \
struct sockaddr * from, __socklen_t *fromlenaddr, \
struct sctp_sndrcvinfo *sinfo, int *msg_flags); }
475 AUE_PREAD STD { ssize_t pread(int fd, void *buf, \
diff --git a/sys/kern/tty.c b/sys/kern/tty.c
index e2a0fa3..373fcc3 100644
--- a/sys/kern/tty.c
+++ b/sys/kern/tty.c
@@ -123,9 +123,10 @@ tty_watermarks(struct tty *tp)
}
static int
-tty_drain(struct tty *tp)
+tty_drain(struct tty *tp, int leaving)
{
- int error;
+ size_t bytesused;
+ int error, revokecnt;
if (ttyhook_hashook(tp, getc_inject))
/* buffer is inaccessible */
@@ -134,11 +135,27 @@ tty_drain(struct tty *tp)
while (ttyoutq_bytesused(&tp->t_outq) > 0) {
ttydevsw_outwakeup(tp);
/* Could be handled synchronously. */
- if (ttyoutq_bytesused(&tp->t_outq) == 0)
+ bytesused = ttyoutq_bytesused(&tp->t_outq);
+ if (bytesused == 0)
return (0);
/* Wait for data to be drained. */
- error = tty_wait(tp, &tp->t_outwait);
+ if (leaving) {
+ revokecnt = tp->t_revokecnt;
+ error = tty_timedwait(tp, &tp->t_outwait, hz);
+ switch (error) {
+ case ERESTART:
+ if (revokecnt != tp->t_revokecnt)
+ error = 0;
+ break;
+ case EWOULDBLOCK:
+ if (ttyoutq_bytesused(&tp->t_outq) < bytesused)
+ error = 0;
+ break;
+ }
+ } else
+ error = tty_wait(tp, &tp->t_outwait);
+
if (error)
return (error);
}
@@ -191,10 +208,8 @@ ttydev_leave(struct tty *tp)
/* Drain any output. */
MPASS((tp->t_flags & TF_STOPPED) == 0);
- if (!tty_gone(tp)) {
- while (tty_drain(tp) == ERESTART)
- ;
- }
+ if (!tty_gone(tp))
+ tty_drain(tp, 1);
ttydisc_close(tp);
@@ -1392,14 +1407,14 @@ tty_timedwait(struct tty *tp, struct cv *cv, int hz)
error = cv_timedwait_sig(cv, tp->t_mtx, hz);
- /* Restart the system call when we may have been revoked. */
- if (tp->t_revokecnt != revokecnt)
- return (ERESTART);
-
/* Bail out when the device slipped away. */
if (tty_gone(tp))
return (ENXIO);
+ /* Restart the system call when we may have been revoked. */
+ if (tp->t_revokecnt != revokecnt)
+ return (ERESTART);
+
return (error);
}
@@ -1528,7 +1543,7 @@ tty_generic_ioctl(struct tty *tp, u_long cmd, void *data, int fflag,
/* Set terminal flags through tcsetattr(). */
if (cmd == TIOCSETAW || cmd == TIOCSETAF) {
- error = tty_drain(tp);
+ error = tty_drain(tp, 0);
if (error)
return (error);
if (cmd == TIOCSETAF)
@@ -1707,7 +1722,7 @@ tty_generic_ioctl(struct tty *tp, u_long cmd, void *data, int fflag,
}
case TIOCDRAIN:
/* Drain TTY output. */
- return tty_drain(tp);
+ return tty_drain(tp, 0);
case TIOCCONS:
/* Set terminal as console TTY. */
if (*(int *)data) {
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index 43dd56b..6d423ba 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -38,7 +38,6 @@ __FBSDID("$FreeBSD$");
#include "opt_capsicum.h"
#include "opt_inet.h"
#include "opt_inet6.h"
-#include "opt_sctp.h"
#include "opt_compat.h"
#include "opt_ktrace.h"
@@ -95,13 +94,6 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_extern.h>
#include <vm/uma.h>
-#if defined(INET) || defined(INET6)
-#ifdef SCTP
-#include <netinet/sctp.h>
-#include <netinet/sctp_peeloff.h>
-#endif /* SCTP */
-#endif /* INET || INET6 */
-
/*
* Flags for accept1() and kern_accept4(), in addition to SOCK_CLOEXEC
* and SOCK_NONBLOCK.
@@ -198,7 +190,7 @@ SYSCTL_PROC(_kern_ipc, OID_AUTO, sfstat, CTLTYPE_OPAQUE | CTLFLAG_RW,
* capability rights are present.
* A reference on the file entry is held upon returning.
*/
-static int
+int
getsock_cap(struct filedesc *fdp, int fd, cap_rights_t *rightsp,
struct file **fpp, u_int *fflagp)
{
@@ -3206,484 +3198,3 @@ out:
return (error);
}
-
-/*
- * SCTP syscalls.
- * Functionality only compiled in if SCTP is defined in the kernel Makefile,
- * otherwise all return EOPNOTSUPP.
- * XXX: We should make this loadable one day.
- */
-int
-sys_sctp_peeloff(td, uap)
- struct thread *td;
- struct sctp_peeloff_args /* {
- int sd;
- caddr_t name;
- } */ *uap;
-{
-#if (defined(INET) || defined(INET6)) && defined(SCTP)
- struct file *nfp = NULL;
- struct socket *head, *so;
- cap_rights_t rights;
- u_int fflag;
- int error, fd;
-
- AUDIT_ARG_FD(uap->sd);
- error = fgetsock(td, uap->sd, cap_rights_init(&rights, CAP_PEELOFF),
- &head, &fflag);
- if (error != 0)
- goto done2;
- if (head->so_proto->pr_protocol != IPPROTO_SCTP) {
- error = EOPNOTSUPP;
- goto done;
- }
- error = sctp_can_peel_off(head, (sctp_assoc_t)uap->name);
- if (error != 0)
- goto done;
- /*
- * At this point we know we do have a assoc to pull
- * we proceed to get the fd setup. This may block
- * but that is ok.
- */
-
- error = falloc(td, &nfp, &fd, 0);
- if (error != 0)
- goto done;
- td->td_retval[0] = fd;
-
- CURVNET_SET(head->so_vnet);
- so = sonewconn(head, SS_ISCONNECTED);
- if (so == NULL) {
- error = ENOMEM;
- goto noconnection;
- }
- /*
- * Before changing the flags on the socket, we have to bump the
- * reference count. Otherwise, if the protocol calls sofree(),
- * the socket will be released due to a zero refcount.
- */
- SOCK_LOCK(so);
- soref(so); /* file descriptor reference */
- SOCK_UNLOCK(so);
-
- ACCEPT_LOCK();
-
- TAILQ_REMOVE(&head->so_comp, so, so_list);
- head->so_qlen--;
- so->so_state |= (head->so_state & SS_NBIO);
- so->so_state &= ~SS_NOFDREF;
- so->so_qstate &= ~SQ_COMP;
- so->so_head = NULL;
- ACCEPT_UNLOCK();
- finit(nfp, fflag, DTYPE_SOCKET, so, &socketops);
- error = sctp_do_peeloff(head, so, (sctp_assoc_t)uap->name);
- if (error != 0)
- goto noconnection;
- if (head->so_sigio != NULL)
- fsetown(fgetown(&head->so_sigio), &so->so_sigio);
-
-noconnection:
- /*
- * close the new descriptor, assuming someone hasn't ripped it
- * out from under us.
- */
- if (error != 0)
- fdclose(td->td_proc->p_fd, nfp, fd, td);
-
- /*
- * Release explicitly held references before returning.
- */
- CURVNET_RESTORE();
-done:
- if (nfp != NULL)
- fdrop(nfp, td);
- fputsock(head);
-done2:
- return (error);
-#else /* SCTP */
- return (EOPNOTSUPP);
-#endif /* SCTP */
-}
-
-int
-sys_sctp_generic_sendmsg (td, uap)
- struct thread *td;
- struct sctp_generic_sendmsg_args /* {
- int sd,
- caddr_t msg,
- int mlen,
- caddr_t to,
- __socklen_t tolen,
- struct sctp_sndrcvinfo *sinfo,
- int flags
- } */ *uap;
-{
-#if (defined(INET) || defined(INET6)) && defined(SCTP)
- struct sctp_sndrcvinfo sinfo, *u_sinfo = NULL;
- struct socket *so;
- struct file *fp = NULL;
- struct sockaddr *to = NULL;
-#ifdef KTRACE
- struct uio *ktruio = NULL;
-#endif
- struct uio auio;
- struct iovec iov[1];
- cap_rights_t rights;
- int error = 0, len;
-
- if (uap->sinfo != NULL) {
- error = copyin(uap->sinfo, &sinfo, sizeof (sinfo));
- if (error != 0)
- return (error);
- u_sinfo = &sinfo;
- }
-
- cap_rights_init(&rights, CAP_SEND);
- if (uap->tolen != 0) {
- error = getsockaddr(&to, uap->to, uap->tolen);
- if (error != 0) {
- to = NULL;
- goto sctp_bad2;
- }
- cap_rights_set(&rights, CAP_CONNECT);
- }
-
- AUDIT_ARG_FD(uap->sd);
- error = getsock_cap(td->td_proc->p_fd, uap->sd, &rights, &fp, NULL);
- if (error != 0)
- goto sctp_bad;
-#ifdef KTRACE
- if (to && (KTRPOINT(td, KTR_STRUCT)))
- ktrsockaddr(to);
-#endif
-
- iov[0].iov_base = uap->msg;
- iov[0].iov_len = uap->mlen;
-
- so = (struct socket *)fp->f_data;
- if (so->so_proto->pr_protocol != IPPROTO_SCTP) {
- error = EOPNOTSUPP;
- goto sctp_bad;
- }
-#ifdef MAC
- error = mac_socket_check_send(td->td_ucred, so);
- if (error != 0)
- goto sctp_bad;
-#endif /* MAC */
-
- auio.uio_iov = iov;
- auio.uio_iovcnt = 1;
- auio.uio_segflg = UIO_USERSPACE;
- auio.uio_rw = UIO_WRITE;
- auio.uio_td = td;
- auio.uio_offset = 0; /* XXX */
- auio.uio_resid = 0;
- len = auio.uio_resid = uap->mlen;
- CURVNET_SET(so->so_vnet);
- error = sctp_lower_sosend(so, to, &auio, (struct mbuf *)NULL,
- (struct mbuf *)NULL, uap->flags, u_sinfo, td);
- CURVNET_RESTORE();
- if (error != 0) {
- if (auio.uio_resid != len && (error == ERESTART ||
- error == EINTR || error == EWOULDBLOCK))
- error = 0;
- /* Generation of SIGPIPE can be controlled per socket. */
- if (error == EPIPE && !(so->so_options & SO_NOSIGPIPE) &&
- !(uap->flags & MSG_NOSIGNAL)) {
- PROC_LOCK(td->td_proc);
- tdsignal(td, SIGPIPE);
- PROC_UNLOCK(td->td_proc);
- }
- }
- if (error == 0)
- td->td_retval[0] = len - auio.uio_resid;
-#ifdef KTRACE
- if (ktruio != NULL) {
- ktruio->uio_resid = td->td_retval[0];
- ktrgenio(uap->sd, UIO_WRITE, ktruio, error);
- }
-#endif /* KTRACE */
-sctp_bad:
- if (fp != NULL)
- fdrop(fp, td);
-sctp_bad2:
- free(to, M_SONAME);
- return (error);
-#else /* SCTP */
- return (EOPNOTSUPP);
-#endif /* SCTP */
-}
-
-int
-sys_sctp_generic_sendmsg_iov(td, uap)
- struct thread *td;
- struct sctp_generic_sendmsg_iov_args /* {
- int sd,
- struct iovec *iov,
- int iovlen,
- caddr_t to,
- __socklen_t tolen,
- struct sctp_sndrcvinfo *sinfo,
- int flags
- } */ *uap;
-{
-#if (defined(INET) || defined(INET6)) && defined(SCTP)
- struct sctp_sndrcvinfo sinfo, *u_sinfo = NULL;
- struct socket *so;
- struct file *fp = NULL;
- struct sockaddr *to = NULL;
-#ifdef KTRACE
- struct uio *ktruio = NULL;
-#endif
- struct uio auio;
- struct iovec *iov, *tiov;
- cap_rights_t rights;
- ssize_t len;
- int error, i;
-
- if (uap->sinfo != NULL) {
- error = copyin(uap->sinfo, &sinfo, sizeof (sinfo));
- if (error != 0)
- return (error);
- u_sinfo = &sinfo;
- }
- cap_rights_init(&rights, CAP_SEND);
- if (uap->tolen != 0) {
- error = getsockaddr(&to, uap->to, uap->tolen);
- if (error != 0) {
- to = NULL;
- goto sctp_bad2;
- }
- cap_rights_set(&rights, CAP_CONNECT);
- }
-
- AUDIT_ARG_FD(uap->sd);
- error = getsock_cap(td->td_proc->p_fd, uap->sd, &rights, &fp, NULL);
- if (error != 0)
- goto sctp_bad1;
-
-#ifdef COMPAT_FREEBSD32
- if (SV_CURPROC_FLAG(SV_ILP32))
- error = freebsd32_copyiniov((struct iovec32 *)uap->iov,
- uap->iovlen, &iov, EMSGSIZE);
- else
-#endif
- error = copyiniov(uap->iov, uap->iovlen, &iov, EMSGSIZE);
- if (error != 0)
- goto sctp_bad1;
-#ifdef KTRACE
- if (to && (KTRPOINT(td, KTR_STRUCT)))
- ktrsockaddr(to);
-#endif
-
- so = (struct socket *)fp->f_data;
- if (so->so_proto->pr_protocol != IPPROTO_SCTP) {
- error = EOPNOTSUPP;
- goto sctp_bad;
- }
-#ifdef MAC
- error = mac_socket_check_send(td->td_ucred, so);
- if (error != 0)
- goto sctp_bad;
-#endif /* MAC */
-
- auio.uio_iov = iov;
- auio.uio_iovcnt = uap->iovlen;
- auio.uio_segflg = UIO_USERSPACE;
- auio.uio_rw = UIO_WRITE;
- auio.uio_td = td;
- auio.uio_offset = 0; /* XXX */
- auio.uio_resid = 0;
- tiov = iov;
- for (i = 0; i <uap->iovlen; i++, tiov++) {
- if ((auio.uio_resid += tiov->iov_len) < 0) {
- error = EINVAL;
- goto sctp_bad;
- }
- }
- len = auio.uio_resid;
- CURVNET_SET(so->so_vnet);
- error = sctp_lower_sosend(so, to, &auio,
- (struct mbuf *)NULL, (struct mbuf *)NULL,
- uap->flags, u_sinfo, td);
- CURVNET_RESTORE();
- if (error != 0) {
- if (auio.uio_resid != len && (error == ERESTART ||
- error == EINTR || error == EWOULDBLOCK))
- error = 0;
- /* Generation of SIGPIPE can be controlled per socket */
- if (error == EPIPE && !(so->so_options & SO_NOSIGPIPE) &&
- !(uap->flags & MSG_NOSIGNAL)) {
- PROC_LOCK(td->td_proc);
- tdsignal(td, SIGPIPE);
- PROC_UNLOCK(td->td_proc);
- }
- }
- if (error == 0)
- td->td_retval[0] = len - auio.uio_resid;
-#ifdef KTRACE
- if (ktruio != NULL) {
- ktruio->uio_resid = td->td_retval[0];
- ktrgenio(uap->sd, UIO_WRITE, ktruio, error);
- }
-#endif /* KTRACE */
-sctp_bad:
- free(iov, M_IOV);
-sctp_bad1:
- if (fp != NULL)
- fdrop(fp, td);
-sctp_bad2:
- free(to, M_SONAME);
- return (error);
-#else /* SCTP */
- return (EOPNOTSUPP);
-#endif /* SCTP */
-}
-
-int
-sys_sctp_generic_recvmsg(td, uap)
- struct thread *td;
- struct sctp_generic_recvmsg_args /* {
- int sd,
- struct iovec *iov,
- int iovlen,
- struct sockaddr *from,
- __socklen_t *fromlenaddr,
- struct sctp_sndrcvinfo *sinfo,
- int *msg_flags
- } */ *uap;
-{
-#if (defined(INET) || defined(INET6)) && defined(SCTP)
- uint8_t sockbufstore[256];
- struct uio auio;
- struct iovec *iov, *tiov;
- struct sctp_sndrcvinfo sinfo;
- struct socket *so;
- struct file *fp = NULL;
- struct sockaddr *fromsa;
- cap_rights_t rights;
-#ifdef KTRACE
- struct uio *ktruio = NULL;
-#endif
- ssize_t len;
- int error, fromlen, i, msg_flags;
-
- AUDIT_ARG_FD(uap->sd);
- error = getsock_cap(td->td_proc->p_fd, uap->sd,
- cap_rights_init(&rights, CAP_RECV), &fp, NULL);
- if (error != 0)
- return (error);
-#ifdef COMPAT_FREEBSD32
- if (SV_CURPROC_FLAG(SV_ILP32))
- error = freebsd32_copyiniov((struct iovec32 *)uap->iov,
- uap->iovlen, &iov, EMSGSIZE);
- else
-#endif
- error = copyiniov(uap->iov, uap->iovlen, &iov, EMSGSIZE);
- if (error != 0)
- goto out1;
-
- so = fp->f_data;
- if (so->so_proto->pr_protocol != IPPROTO_SCTP) {
- error = EOPNOTSUPP;
- goto out;
- }
-#ifdef MAC
- error = mac_socket_check_receive(td->td_ucred, so);
- if (error != 0)
- goto out;
-#endif /* MAC */
-
- if (uap->fromlenaddr != NULL) {
- error = copyin(uap->fromlenaddr, &fromlen, sizeof (fromlen));
- if (error != 0)
- goto out;
- } else {
- fromlen = 0;
- }
- if (uap->msg_flags) {
- error = copyin(uap->msg_flags, &msg_flags, sizeof (int));
- if (error != 0)
- goto out;
- } else {
- msg_flags = 0;
- }
- auio.uio_iov = iov;
- auio.uio_iovcnt = uap->iovlen;
- auio.uio_segflg = UIO_USERSPACE;
- auio.uio_rw = UIO_READ;
- auio.uio_td = td;
- auio.uio_offset = 0; /* XXX */
- auio.uio_resid = 0;
- tiov = iov;
- for (i = 0; i <uap->iovlen; i++, tiov++) {
- if ((auio.uio_resid += tiov->iov_len) < 0) {
- error = EINVAL;
- goto out;
- }
- }
- len = auio.uio_resid;
- fromsa = (struct sockaddr *)sockbufstore;
-
-#ifdef KTRACE
- if (KTRPOINT(td, KTR_GENIO))
- ktruio = cloneuio(&auio);
-#endif /* KTRACE */
- memset(&sinfo, 0, sizeof(struct sctp_sndrcvinfo));
- CURVNET_SET(so->so_vnet);
- error = sctp_sorecvmsg(so, &auio, (struct mbuf **)NULL,
- fromsa, fromlen, &msg_flags,
- (struct sctp_sndrcvinfo *)&sinfo, 1);
- CURVNET_RESTORE();
- if (error != 0) {
- if (auio.uio_resid != len && (error == ERESTART ||
- error == EINTR || error == EWOULDBLOCK))
- error = 0;
- } else {
- if (uap->sinfo)
- error = copyout(&sinfo, uap->sinfo, sizeof (sinfo));
- }
-#ifdef KTRACE
- if (ktruio != NULL) {
- ktruio->uio_resid = len - auio.uio_resid;
- ktrgenio(uap->sd, UIO_READ, ktruio, error);
- }
-#endif /* KTRACE */
- if (error != 0)
- goto out;
- td->td_retval[0] = len - auio.uio_resid;
-
- if (fromlen && uap->from) {
- len = fromlen;
- if (len <= 0 || fromsa == 0)
- len = 0;
- else {
- len = MIN(len, fromsa->sa_len);
- error = copyout(fromsa, uap->from, (size_t)len);
- if (error != 0)
- goto out;
- }
- error = copyout(&len, uap->fromlenaddr, sizeof (socklen_t));
- if (error != 0)
- goto out;
- }
-#ifdef KTRACE
- if (KTRPOINT(td, KTR_STRUCT))
- ktrsockaddr(fromsa);
-#endif
- if (uap->msg_flags) {
- error = copyout(&msg_flags, uap->msg_flags, sizeof (int));
- if (error != 0)
- goto out;
- }
-out:
- free(iov, M_IOV);
-out1:
- if (fp != NULL)
- fdrop(fp, td);
-
- return (error);
-#else /* SCTP */
- return (EOPNOTSUPP);
-#endif /* SCTP */
-}
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index 5a37b0b..19feecd 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -667,6 +667,10 @@ bd_speedup(void)
mtx_unlock(&bdlock);
}
+#ifndef NSWBUF_MIN
+#define NSWBUF_MIN 16
+#endif
+
#ifdef __i386__
#define TRANSIENT_DENOM 5
#else
@@ -778,11 +782,10 @@ kern_vfs_bio_buffer_alloc(caddr_t v, long physmem_est)
* swbufs are used as temporary holders for I/O, such as paging I/O.
* We have no less then 16 and no more then 256.
*/
- nswbuf = max(min(nbuf/4, 256), 16);
-#ifdef NSWBUF_MIN
+ nswbuf = min(nbuf / 4, 256);
+ TUNABLE_INT_FETCH("kern.nswbuf", &nswbuf);
if (nswbuf < NSWBUF_MIN)
nswbuf = NSWBUF_MIN;
-#endif
/*
* Reserve space for the buffer cache buffers
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index 617bda0..b86ffa7 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -504,13 +504,16 @@ vn_rdwr(enum uio_rw rw, struct vnode *vp, void *base, int len, off_t offset,
error = 0;
if ((ioflg & IO_NODELOCKED) == 0) {
- if (rw == UIO_READ) {
- rl_cookie = vn_rangelock_rlock(vp, offset,
- offset + len);
- } else {
- rl_cookie = vn_rangelock_wlock(vp, offset,
- offset + len);
- }
+ if ((ioflg & IO_RANGELOCKED) == 0) {
+ if (rw == UIO_READ) {
+ rl_cookie = vn_rangelock_rlock(vp, offset,
+ offset + len);
+ } else {
+ rl_cookie = vn_rangelock_wlock(vp, offset,
+ offset + len);
+ }
+ } else
+ rl_cookie = NULL;
mp = NULL;
if (rw == UIO_WRITE) {
if (vp->v_type != VCHR &&
@@ -2234,12 +2237,10 @@ vn_utimes_perm(struct vnode *vp, struct vattr *vap, struct ucred *cred,
{
int error;
- error = VOP_ACCESSX(vp, VWRITE_ATTRIBUTES, cred, td);
-
/*
- * From utimes(2):
- * Grant permission if the caller is the owner of the file or
- * the super-user. If the time pointer is null, then write
+ * Grant permission if the caller is the owner of the file, or
+ * the super-user, or has ACL_WRITE_ATTRIBUTES permission on
+ * on the file. If the time pointer is null, then write
* permission on the file is also sufficient.
*
* From NFSv4.1, draft 21, 6.2.1.3.1, Discussion of Mask Attributes:
@@ -2247,6 +2248,7 @@ vn_utimes_perm(struct vnode *vp, struct vattr *vap, struct ucred *cred,
* will be allowed to set the times [..] to the current
* server time.
*/
+ error = VOP_ACCESSX(vp, VWRITE_ATTRIBUTES, cred, td);
if (error != 0 && (vap->va_vaflags & VA_UTIMES_NULL) != 0)
error = VOP_ACCESS(vp, VWRITE, cred, td);
return (error);
OpenPOWER on IntegriCloud