Merge ^/head r318964 through r319164.

This commit is contained in:
Dimitry Andric 2017-05-29 22:25:33 +00:00
commit a773cead9f
117 changed files with 3316 additions and 628 deletions

View File

@ -150,6 +150,8 @@ OLD_FILES+=usr/lib/clang/4.0.0/lib/freebsd/libclang_rt.ubsan_standalone_cxx-x86_
OLD_DIRS+=usr/lib/clang/4.0.0/lib/freebsd
OLD_DIRS+=usr/lib/clang/4.0.0/lib
OLD_DIRS+=usr/lib/clang/4.0.0
# 20170529: mount.conf(8) -> mount.conf(5)
OLD_FILES+=usr/share/man/man8/mount.conf.8.gz
# 20170525: remove misleading template
OLD_FILES+=usr/share/misc/man.template
# 20170525: disconnect the roff docs from the build
@ -222,6 +224,10 @@ OLD_FILES+=usr/share/doc/usd/21.troff/paper.ascii.gz
OLD_FILES+=usr/share/doc/usd/22.trofftut/paper.ascii.gz
OLD_FILES+=usr/share/doc/usd/Title.ascii.gz
OLD_FILES+=usr/share/doc/usd/contents.ascii.gz
# 20170523: 64-bit inode support, library version bumps
OLD_LIBS+=lib/libzfs.so.2
OLD_LIBS+=usr/lib/libarchive.so.6
OLD_LIBS+=usr/lib/libmilter.so.5
# 20170427: NATM configuration support removed
OLD_FILES+=etc/rc.d/atm1
OLD_FILES+=etc/rc.d/atm2

View File

@ -480,7 +480,7 @@ powerpc-*-lynxos*) targ_emul=ppclynx ;;
rs6000-*-aix5*) targ_emul=aix5rs6 ;;
rs6000-*-aix*) targ_emul=aixrs6
;;
s390x-*-freebsd*) targ_emul=elf64_s390
s390x-*-freebsd*) targ_emul=elf64_s390
targ_extra_emuls=elf_s390
targ_extra_libpath=$targ_extra_emuls
tdir_elf_s390=`echo ${targ_alias} | sed -e 's/s390x/s390/'` ;;
@ -490,7 +490,7 @@ s390x-*-linux*) targ_emul=elf64_s390
tdir_elf_s390=`echo ${targ_alias} | sed -e 's/s390x/s390/'` ;;
s390x-*-tpf*) targ_emul=elf64_s390
tdir_elf_s390=`echo ${targ_alias} | sed -e 's/s390x/s390/'` ;;
s390-*-freebsd*) targ_emul=elf_s390
s390-*-freebsd*) targ_emul=elf_s390
targ64_extra_emuls=elf64_s390
targ64_extra_libpath=elf64_s390
tdir_elf64_s390=`echo ${targ_alias} | sed -e 's/s390/s390x/'`

View File

@ -47,39 +47,49 @@ struct c4iw_stats c4iw_stats;
static void copy_wr_to_sq(struct t4_wq *wq, union t4_wr *wqe, u8 len16)
{
u64 *src, *dst;
void *src, *dst;
uintptr_t end;
int total, len;
src = (u64 *)wqe;
dst = (u64 *)((u8 *)wq->sq.queue + wq->sq.wq_pidx * T4_EQ_ENTRY_SIZE);
src = &wqe->flits[0];
dst = &wq->sq.queue->flits[wq->sq.wq_pidx *
(T4_EQ_ENTRY_SIZE / sizeof(__be64))];
if (t4_sq_onchip(wq)) {
len16 = align(len16, 4);
wc_wmb();
}
while (len16) {
*dst++ = *src++;
if (dst == (u64 *)&wq->sq.queue[wq->sq.size])
dst = (u64 *)wq->sq.queue;
*dst++ = *src++;
if (dst == (u64 *)&wq->sq.queue[wq->sq.size])
dst = (u64 *)wq->sq.queue;
len16--;
total = len16 * 16;
end = (uintptr_t)&wq->sq.queue[wq->sq.size];
if (__predict_true((uintptr_t)dst + total <= end)) {
/* Won't wrap around. */
memcpy(dst, src, total);
} else {
len = end - (uintptr_t)dst;
memcpy(dst, src, len);
memcpy(wq->sq.queue, src + len, total - len);
}
}
static void copy_wr_to_rq(struct t4_wq *wq, union t4_recv_wr *wqe, u8 len16)
{
u64 *src, *dst;
void *src, *dst;
uintptr_t end;
int total, len;
src = (u64 *)wqe;
dst = (u64 *)((u8 *)wq->rq.queue + wq->rq.wq_pidx * T4_EQ_ENTRY_SIZE);
while (len16) {
*dst++ = *src++;
if (dst >= (u64 *)&wq->rq.queue[wq->rq.size])
dst = (u64 *)wq->rq.queue;
*dst++ = *src++;
if (dst >= (u64 *)&wq->rq.queue[wq->rq.size])
dst = (u64 *)wq->rq.queue;
len16--;
src = &wqe->flits[0];
dst = &wq->rq.queue->flits[wq->rq.wq_pidx *
(T4_EQ_ENTRY_SIZE / sizeof(__be64))];
total = len16 * 16;
end = (uintptr_t)&wq->rq.queue[wq->rq.size];
if (__predict_true((uintptr_t)dst + total <= end)) {
/* Won't wrap around. */
memcpy(dst, src, total);
} else {
len = end - (uintptr_t)dst;
memcpy(dst, src, len);
memcpy(wq->rq.queue, src + len, total - len);
}
}

View File

@ -20,12 +20,14 @@ saveseed_cmd="${name}_stop"
save_dev_random()
{
oumask=`umask`
umask 077
for f ; do
if :>>"$f" ; then
debug "saving entropy to $f"
dd if=/dev/random of="$f" bs=4096 count=1 2>/dev/null
fi
debug "saving entropy to $f"
dd if=/dev/random of="$f" bs=4096 count=1 status=none &&
chmod 600 "$f"
done
umask ${oumask}
}
feed_dev_random()

View File

@ -28,7 +28,7 @@
.\" @(#)getdirentries.2 8.2 (Berkeley) 5/3/95
.\" $FreeBSD$
.\"
.Dd May 3, 1995
.Dd May 28, 2017
.Dt GETDIRENTRIES 2
.Os
.Sh NAME
@ -71,10 +71,11 @@ The data in the buffer is a series of
.Vt dirent
structures each containing the following entries:
.Bd -literal -offset indent
uint32_t d_fileno;
uint16_t d_reclen;
uint8_t d_type;
uint8_t d_namlen;
ino_t d_fileno;
off_t d_off;
uint16_t d_reclen;
uint8_t d_type;
uint16_t d_namlen;
char d_name[MAXNAMLEN + 1]; /* see below */
.Ed
.Pp
@ -124,7 +125,10 @@ or
A value of zero is returned when
the end of the directory has been reached.
.Pp
The
If the
.Fa basep
pointer value is non-NULL ,
the
.Fn getdirentries
system call writes the position of the block read into the location pointed to by
.Fa basep .
@ -157,7 +161,7 @@ is not a valid file descriptor open for reading.
.It Bq Er EFAULT
Either
.Fa buf
or
or non-NULL
.Fa basep
point outside the allocated address space.
.It Bq Er EINVAL

View File

@ -1,18 +1,13 @@
# $FreeBSD$
.PATH: ${.CURDIR:H}/resolv
PACKAGE= tests
TESTSDIR= ${TESTSBASE}/lib/libc/nss
BINDIR= ${TESTSDIR}
.PATH: ${.CURDIR:H}/resolv
${PACKAGE}FILES+= mach
WARNS?= 1
CFLAGS+= -I${SRCTOP}/tests
ATF_TESTS_C+= getaddrinfo_test
ATF_TESTS_C+= getgr_test
ATF_TESTS_C+= gethostby_test
@ -23,4 +18,10 @@ ATF_TESTS_C+= getrpc_test
ATF_TESTS_C+= getserv_test
ATF_TESTS_C+= getusershell_test
${PACKAGE}FILES+= mach
WARNS?= 3
CFLAGS+= -I${SRCTOP}/tests
.include <bsd.test.mk>

View File

@ -28,7 +28,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
@ -125,7 +125,8 @@ compare_addrinfo_(struct addrinfo *ai1, struct addrinfo *ai2)
}
static int
compare_addrinfo(struct addrinfo *ai1, struct addrinfo *ai2, void *mdata)
compare_addrinfo(struct addrinfo *ai1, struct addrinfo *ai2,
void *mdata __unused)
{
int rv;
@ -144,7 +145,7 @@ compare_addrinfo(struct addrinfo *ai1, struct addrinfo *ai2, void *mdata)
return (rv);
}
void
static void
free_addrinfo(struct addrinfo *ai)
{
if (ai == NULL)
@ -164,30 +165,30 @@ sdump_addrinfo(struct addrinfo *ai, char *buffer, size_t buflen)
ai->ai_flags, ai->ai_family, ai->ai_socktype, ai->ai_protocol,
ai->ai_addrlen);
buffer += written;
if (written > buflen)
if (written > (int)buflen)
return;
buflen -= written;
written = snprintf(buffer, buflen, "%s ",
ai->ai_canonname == NULL ? "(null)" : ai->ai_canonname);
buffer += written;
if (written > buflen)
if (written > (int)buflen)
return;
buflen -= written;
if (ai->ai_addr == NULL) {
written = snprintf(buffer, buflen, "(null)");
buffer += written;
if (written > buflen)
if (written > (int)buflen)
return;
buflen -= written;
} else {
for (i = 0; i < ai->ai_addrlen; i++) {
for (i = 0; i < (int)ai->ai_addrlen; i++) {
written = snprintf(buffer, buflen,
i + 1 != ai->ai_addrlen ? "%d." : "%d",
i + 1 != (int)ai->ai_addrlen ? "%d." : "%d",
((unsigned char *)ai->ai_addr)[i]);
buffer += written;
if (written > buflen)
if (written > (int)buflen)
return;
buflen -= written;
@ -199,7 +200,7 @@ sdump_addrinfo(struct addrinfo *ai, char *buffer, size_t buflen)
if (ai->ai_next != NULL) {
written = snprintf(buffer, buflen, ":");
buffer += written;
if (written > buflen)
if (written > (int)buflen)
return;
buflen -= written;
@ -309,12 +310,11 @@ addrinfo_read_snapshot_func(struct addrinfo *ai, char *line)
{
struct addrinfo *ai2;
char *s, *ps;
int i, rv;
int rv;
printf("1 line read from snapshot:\n%s\n", line);
rv = 0;
i = 0;
ps = line;
s = strsep(&ps, ":");
@ -344,7 +344,7 @@ addrinfo_read_snapshot_func(struct addrinfo *ai, char *line)
}
static int
addrinfo_test_correctness(struct addrinfo *ai, void *mdata)
addrinfo_test_correctness(struct addrinfo *ai, void *mdata __unused)
{
printf("testing correctness with the following data:\n");
@ -409,12 +409,20 @@ addrinfo_read_hostlist_func(struct addrinfo *ai, char *line)
return (0);
}
void
run_tests(char *hostlist_file, char *snapshot_file, int ai_family)
static void
run_tests(char *hostlist_file, const char *snapshot_file, int ai_family)
{
struct addrinfo_test_data td, td_snap;
char *snapshot_file_copy;
int rv;
if (snapshot_file == NULL)
snapshot_file_copy = NULL;
else {
snapshot_file_copy = strdup(snapshot_file);
ATF_REQUIRE(snapshot_file_copy != NULL);
}
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = ai_family;
hints.ai_flags = AI_CANONNAME;
@ -477,24 +485,17 @@ run_tests(char *hostlist_file, char *snapshot_file, int ai_family)
TEST_DATA_DESTROY(addrinfo, &td_snap);
TEST_DATA_DESTROY(addrinfo, &td);
free(hostlist_file);
free(snapshot_file);
free(snapshot_file_copy);
}
#define HOSTLIST_FILE "mach"
#define RUN_TESTS(tc, snapshot_file, ai_family) do { \
char *_hostlist_file; \
char *_snapshot_file; \
ATF_REQUIRE(0 < asprintf(&_hostlist_file, "%s/%s", \
atf_tc_get_config_var(tc, "srcdir"), HOSTLIST_FILE)); \
if (snapshot_file == NULL) \
_snapshot_file = NULL; \
else { \
_snapshot_file = strdup(snapshot_file); \
ATF_REQUIRE(_snapshot_file != NULL); \
} \
run_tests(_hostlist_file, _snapshot_file, ai_family); \
} while(0)
run_tests(_hostlist_file, snapshot_file, ai_family); \
free(_hostlist_file); \
} while (0)
ATF_TC_WITHOUT_HEAD(pf_unspec);
ATF_TC_BODY(pf_unspec, tc)

View File

@ -49,8 +49,6 @@ enum test_methods {
TEST_BUILD_SNAPSHOT = 16,
};
static enum test_methods method = TEST_BUILD_SNAPSHOT;
DECLARE_TEST_DATA(group)
DECLARE_TEST_FILE_SNAPSHOT(group)
DECLARE_1PASS_TEST(group)
@ -104,7 +102,7 @@ clone_group(struct group *dest, struct group const *src)
for (cp = src->gr_mem; *cp; ++cp)
++members_num;
dest->gr_mem = calloc(1, (members_num + 1) * sizeof(char *));
dest->gr_mem = calloc(members_num + 1, sizeof(char *));
ATF_REQUIRE(dest->gr_mem != NULL);
for (cp = src->gr_mem; *cp; ++cp) {
@ -179,7 +177,7 @@ sdump_group(struct group *grp, char *buffer, size_t buflen)
written = snprintf(buffer, buflen, "%s:%s:%d:",
grp->gr_name, grp->gr_passwd, grp->gr_gid);
buffer += written;
if (written > buflen)
if (written > (int)buflen)
return;
buflen -= written;
@ -189,7 +187,7 @@ sdump_group(struct group *grp, char *buffer, size_t buflen)
written = snprintf(buffer, buflen, "%s%s",
cp == grp->gr_mem ? "" : ",", *cp);
buffer += written;
if (written > buflen)
if (written > (int)buflen)
return;
buflen -= written;
@ -309,7 +307,7 @@ group_fill_test_data(struct group_test_data *td)
}
static int
group_test_correctness(struct group *grp, void *mdata)
group_test_correctness(struct group *grp, void *mdata __unused)
{
printf("testing correctness with the following data:\n");
dump_group(grp);
@ -387,7 +385,7 @@ group_test_getgrgid(struct group *grp_model, void *mdata)
}
static int
group_test_getgrent(struct group *grp, void *mdata)
group_test_getgrent(struct group *grp, void *mdata __unused)
{
/* Only correctness can be checked when doing 1-pass test for
* getgrent(). */

View File

@ -87,8 +87,6 @@ static int hostent_test_gethostbyaddr(struct hostent *, void *);
static int hostent_test_getaddrinfo_eq(struct hostent *, void *);
static int hostent_test_getnameinfo_eq(struct hostent *, void *);
static void usage(void) __attribute__((__noreturn__));
IMPLEMENT_TEST_DATA(hostent)
IMPLEMENT_TEST_FILE_SNAPSHOT(hostent)
IMPLEMENT_1PASS_TEST(hostent)
@ -163,8 +161,7 @@ clone_hostent(struct hostent *dest, struct hostent const *src)
for (cp = src->h_aliases; *cp; ++cp)
++aliases_num;
dest->h_aliases = calloc(1, (aliases_num + 1) *
sizeof(char *));
dest->h_aliases = calloc(aliases_num + 1, sizeof(char *));
ATF_REQUIRE(dest->h_aliases != NULL);
for (cp = src->h_aliases; *cp; ++cp) {
@ -178,7 +175,7 @@ clone_hostent(struct hostent *dest, struct hostent const *src)
for (cp = src->h_addr_list; *cp; ++cp)
++addrs_num;
dest->h_addr_list = calloc(1, (addrs_num + 1) * sizeof(char *));
dest->h_addr_list = calloc(addrs_num + 1, sizeof(char *));
ATF_REQUIRE(dest->h_addr_list != NULL);
for (cp = src->h_addr_list; *cp; ++cp) {
@ -413,7 +410,7 @@ sdump_hostent(struct hostent *ht, char *buffer, size_t buflen)
written = snprintf(buffer, buflen, "%s %d %d",
ht->h_name, ht->h_addrtype, ht->h_length);
buffer += written;
if (written > buflen)
if (written > (int)buflen)
return;
buflen -= written;
@ -422,7 +419,7 @@ sdump_hostent(struct hostent *ht, char *buffer, size_t buflen)
for (cp = ht->h_aliases; *cp; ++cp) {
written = snprintf(buffer, buflen, " %s",*cp);
buffer += written;
if (written > buflen)
if (written > (int)buflen)
return;
buflen -= written;
@ -432,59 +429,61 @@ sdump_hostent(struct hostent *ht, char *buffer, size_t buflen)
} else {
written = snprintf(buffer, buflen, " noaliases");
buffer += written;
if (written > buflen)
if (written > (int)buflen)
return;
buflen -= written;
}
} else {
written = snprintf(buffer, buflen, " (null)");
buffer += written;
if (written > buflen)
if (written > (int)buflen)
return;
buflen -= written;
}
written = snprintf(buffer, buflen, " : ");
buffer += written;
if (written > buflen)
if (written > (int)buflen)
return;
buflen -= written;
if (ht->h_addr_list != NULL) {
if (*(ht->h_addr_list) != NULL) {
for (cp = ht->h_addr_list; *cp; ++cp) {
for (i = 0; i < ht->h_length; ++i ) {
written = snprintf(buffer, buflen,
i + 1 != ht->h_length ? "%d." : "%d",
(unsigned char)(*cp)[i]);
buffer += written;
if (written > buflen)
return;
buflen -= written;
for (i = 0; i < (size_t)ht->h_length; ++i) {
written = snprintf(buffer, buflen,
i + 1 != (size_t)ht->h_length ?
"%d." : "%d",
(unsigned char)(*cp)[i]);
buffer += written;
if (written > (int)buflen)
return;
buflen -= written;
if (buflen == 0)
return;
}
if (buflen == 0)
return;
}
if (*(cp + 1) ) {
written = snprintf(buffer, buflen, " ");
buffer += written;
if (written > buflen)
return;
buflen -= written;
}
if (*(cp + 1)) {
written = snprintf(buffer, buflen,
" ");
buffer += written;
if (written > (int)buflen)
return;
buflen -= written;
}
}
} else {
written = snprintf(buffer, buflen, " noaddrs");
buffer += written;
if (written > buflen)
if (written > (int)buflen)
return;
buflen -= written;
}
} else {
written = snprintf(buffer, buflen, " (null)");
buffer += written;
if (written > buflen)
if (written > (int)buflen)
return;
buflen -= written;
}
@ -676,7 +675,7 @@ dump_hostent(struct hostent *result)
}
static int
hostent_test_correctness(struct hostent *ht, void *mdata)
hostent_test_correctness(struct hostent *ht, void *mdata __unused)
{
#ifdef DEBUG
@ -759,7 +758,7 @@ hostent_test_gethostbyaddr(struct hostent *he, void *mdata)
}
static int
hostent_test_getaddrinfo_eq(struct hostent *he, void *mdata)
hostent_test_getaddrinfo_eq(struct hostent *he, void *mdata __unused)
{
struct addrinfo *ai, hints;
int rv;
@ -777,28 +776,30 @@ hostent_test_getaddrinfo_eq(struct hostent *he, void *mdata)
rv = getaddrinfo(he->h_name, NULL, &hints, &ai);
if (rv == 0) {
printf("not ok - shouldn't have been resolved\n");
return (-1);
}
rv = -1;
} else
rv = 0;
} else {
rv = getaddrinfo(he->h_name, NULL, &hints, &ai);
if (rv != 0) {
printf("not ok - should have been resolved\n");
return (-1);
rv = -1;
goto done;
}
rv = is_hostent_equal(he, ai);
if (rv != 0) {
printf("not ok - addrinfo and hostent are not equal\n");
return (-1);
rv = -1;
}
}
return (0);
done:
if (ai != NULL)
freeaddrinfo(ai);
return (rv);
}
static int
hostent_test_getnameinfo_eq(struct hostent *he, void *mdata)
hostent_test_getnameinfo_eq(struct hostent *he, void *mdata __unused)
{
char **cp;
char buffer[NI_MAXHOST];
@ -885,7 +886,7 @@ hostent_test_getnameinfo_eq(struct hostent *he, void *mdata)
* An address might reverse resolve to hostname alias or the
* official hostname, e.g. moon.vub.ac.be.
*/
bool found_a_match;
bool found_a_match = false;
if (strcmp(result->h_name, buffer) == 0) {
found_a_match = true;
@ -921,15 +922,24 @@ hostent_test_getnameinfo_eq(struct hostent *he, void *mdata)
return (0);
}
int
run_tests(const char *hostlist_file, const char *snapshot_file, int af_type,
static int
run_tests(const char *hostlist_file, const char *snapshot_file, int _af_type,
enum test_methods method, bool use_ipv6_mapping)
{
char *snapshot_file_copy;
struct hostent_test_data td, td_addr, td_snap;
res_state statp;
int rv = -2;
switch (af_type) {
if (snapshot_file == NULL)
snapshot_file_copy = NULL;
else {
snapshot_file_copy = strdup(snapshot_file);
ATF_REQUIRE(snapshot_file_copy != NULL);
}
snapshot_file = snapshot_file_copy;
switch (_af_type) {
case AF_INET:
ATF_REQUIRE_FEATURE("inet");
ATF_REQUIRE(!use_ipv6_mapping);
@ -938,7 +948,7 @@ run_tests(const char *hostlist_file, const char *snapshot_file, int af_type,
ATF_REQUIRE_FEATURE("inet6");
break;
default:
atf_tc_fail("unhandled address family: %d", af_type);
atf_tc_fail("unhandled address family: %d", _af_type);
break;
}
@ -947,8 +957,8 @@ run_tests(const char *hostlist_file, const char *snapshot_file, int af_type,
if (statp == NULL || ((statp->options & RES_INIT) == 0 &&
res_ninit(statp) == -1)) {
printf("error: can't init res_state\n");
return (-1);
rv = -1;
goto fin2;
}
if (use_ipv6_mapping)
@ -1052,6 +1062,9 @@ run_tests(const char *hostlist_file, const char *snapshot_file, int af_type,
TEST_DATA_DESTROY(hostent, &td_addr);
TEST_DATA_DESTROY(hostent, &td);
fin2:
free(snapshot_file_copy);
return (rv);
}
@ -1060,30 +1073,24 @@ run_tests(const char *hostlist_file, const char *snapshot_file, int af_type,
#define _RUN_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping) \
do { \
char *_hostlist_file; \
char *_snapshot_file; \
ATF_REQUIRE(0 < asprintf(&_hostlist_file, "%s/%s", \
atf_tc_get_config_var(tc, "srcdir"), HOSTLIST_FILE)); \
if (snapshot_file == NULL) \
_snapshot_file = NULL; \
else { \
_snapshot_file = strdup(snapshot_file); \
ATF_REQUIRE(_snapshot_file != NULL); \
} \
ATF_REQUIRE(run_tests(_hostlist_file, _snapshot_file, af_type, \
ATF_REQUIRE(run_tests(_hostlist_file, snapshot_file, af_type, \
method, use_ipv6_mapping) == 0); \
} while(0)
free(_hostlist_file); \
} while (0)
#define RUN_HOST_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping) \
do { \
use_ipnode_functions = false; \
_RUN_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping); \
} while(0)
} while (0)
#define RUN_IPNODE_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping) \
do { \
use_ipnode_functions = true; \
_RUN_TESTS(tc, snapshot_file, af_type, method, use_ipv6_mapping); \
} while(0)
} while (0)
ATF_TC_WITHOUT_HEAD(gethostbyaddr_ipv4);
ATF_TC_BODY(gethostbyaddr_ipv4, tc)

View File

@ -99,7 +99,7 @@ clone_protoent(struct protoent *dest, struct protoent const *src)
for (cp = src->p_aliases; *cp; ++cp)
++aliases_num;
dest->p_aliases = calloc(1, (aliases_num+1) * sizeof(char *));
dest->p_aliases = calloc(aliases_num + 1, sizeof(char *));
assert(dest->p_aliases != NULL);
for (cp = src->p_aliases; *cp; ++cp) {
@ -172,16 +172,16 @@ sdump_protoent(struct protoent *pe, char *buffer, size_t buflen)
written = snprintf(buffer, buflen, "%s %d",
pe->p_name, pe->p_proto);
buffer += written;
if (written > buflen)
if (written > (int)buflen)
return;
buflen -= written;
if (pe->p_aliases != NULL) {
if (*(pe->p_aliases) != '\0') {
for (cp = pe->p_aliases; *cp; ++cp) {
written = snprintf(buffer, buflen, " %s",*cp);
written = snprintf(buffer, buflen, " %s", *cp);
buffer += written;
if (written > buflen)
if (written > (int)buflen)
return;
buflen -= written;
@ -288,7 +288,7 @@ protoent_fill_test_data(struct protoent_test_data *td)
}
static int
protoent_test_correctness(struct protoent *pe, void *mdata)
protoent_test_correctness(struct protoent *pe, void *mdata __unused)
{
printf("testing correctness with the following data:\n");
dump_protoent(pe);
@ -388,14 +388,14 @@ protoent_test_getprotobynumber(struct protoent *pe_model, void *mdata)
}
static int
protoent_test_getprotoent(struct protoent *pe, void *mdata)
protoent_test_getprotoent(struct protoent *pe, void *mdata __unused)
{
/* Only correctness can be checked when doing 1-pass test for
* getprotoent(). */
return (protoent_test_correctness(pe, NULL));
}
int
static int
run_tests(const char *snapshot_file, enum test_methods method)
{
struct protoent_test_data td, td_snap, td_2pass;

View File

@ -47,8 +47,6 @@ enum test_methods {
TEST_BUILD_SNAPSHOT
};
static enum test_methods method = TEST_BUILD_SNAPSHOT;
DECLARE_TEST_DATA(passwd)
DECLARE_TEST_FILE_SNAPSHOT(passwd)
DECLARE_1PASS_TEST(passwd)
@ -59,7 +57,9 @@ static int compare_passwd(struct passwd *, struct passwd *, void *);
static void free_passwd(struct passwd *);
static void sdump_passwd(struct passwd *, char *, size_t);
#ifdef DEBUG
static void dump_passwd(struct passwd *);
#endif
static int passwd_read_snapshot_func(struct passwd *, char *);
@ -97,7 +97,7 @@ clone_passwd(struct passwd *dest, struct passwd const *src)
}
static int
compare_passwd(struct passwd *pwd1, struct passwd *pwd2, void *mdata)
compare_passwd(struct passwd *pwd1, struct passwd *pwd2, void *mdata __unused)
{
ATF_REQUIRE(pwd1 != NULL);
ATF_REQUIRE(pwd2 != NULL);
@ -142,6 +142,7 @@ sdump_passwd(struct passwd *pwd, char *buffer, size_t buflen)
pwd->pw_fields);
}
#ifdef DEBUG
static void
dump_passwd(struct passwd *pwd)
{
@ -152,6 +153,7 @@ dump_passwd(struct passwd *pwd)
} else
printf("(null)\n");
}
#endif
static int
passwd_read_snapshot_func(struct passwd *pwd, char *line)
@ -251,7 +253,7 @@ passwd_fill_test_data(struct passwd_test_data *td)
}
static int
passwd_test_correctness(struct passwd *pwd, void *mdata)
passwd_test_correctness(struct passwd *pwd, void *mdata __unused)
{
#ifdef DEBUG
@ -363,7 +365,7 @@ passwd_test_getpwuid(struct passwd *pwd_model, void *mdata)
}
static int
passwd_test_getpwent(struct passwd *pwd, void *mdata)
passwd_test_getpwent(struct passwd *pwd, void *mdata __unused)
{
/* Only correctness can be checked when doing 1-pass test for
* getpwent(). */

View File

@ -70,8 +70,6 @@ static int rpcent_test_getrpcbyname(struct rpcent *, void *);
static int rpcent_test_getrpcbynumber(struct rpcent *, void *);
static int rpcent_test_getrpcent(struct rpcent *, void *);
static void usage(void) __attribute__((__noreturn__));
IMPLEMENT_TEST_DATA(rpcent)
IMPLEMENT_TEST_FILE_SNAPSHOT(rpcent)
IMPLEMENT_1PASS_TEST(rpcent)
@ -100,7 +98,7 @@ clone_rpcent(struct rpcent *dest, struct rpcent const *src)
for (cp = src->r_aliases; *cp; ++cp)
++aliases_num;
dest->r_aliases = calloc(1, (aliases_num + 1) * sizeof(char *));
dest->r_aliases = calloc(aliases_num + 1, sizeof(char *));
ATF_REQUIRE(dest->r_aliases != NULL);
for (cp = src->r_aliases; *cp; ++cp) {
@ -173,16 +171,16 @@ sdump_rpcent(struct rpcent *rpc, char *buffer, size_t buflen)
written = snprintf(buffer, buflen, "%s %d",
rpc->r_name, rpc->r_number);
buffer += written;
if (written > buflen)
if (written > (int)buflen)
return;
buflen -= written;
if (rpc->r_aliases != NULL) {
if (*(rpc->r_aliases) != '\0') {
for (cp = rpc->r_aliases; *cp; ++cp) {
written = snprintf(buffer, buflen, " %s",*cp);
written = snprintf(buffer, buflen, " %s", *cp);
buffer += written;
if (written > buflen)
if (written > (int)buflen)
return;
buflen -= written;
@ -289,7 +287,7 @@ rpcent_fill_test_data(struct rpcent_test_data *td)
}
static int
rpcent_test_correctness(struct rpcent *rpc, void *mdata)
rpcent_test_correctness(struct rpcent *rpc, void *mdata __unused)
{
printf("testing correctness with the following data:\n");
@ -390,7 +388,7 @@ rpcent_test_getrpcbynumber(struct rpcent *rpc_model, void *mdata)
}
static int
rpcent_test_getrpcent(struct rpcent *rpc, void *mdata)
rpcent_test_getrpcent(struct rpcent *rpc, void *mdata __unused)
{
/*
@ -400,7 +398,7 @@ rpcent_test_getrpcent(struct rpcent *rpc, void *mdata)
return (rpcent_test_correctness(rpc, NULL));
}
int
static int
run_tests(const char *snapshot_file, enum test_methods method)
{
struct rpcent_test_data td, td_snap, td_2pass;

View File

@ -102,7 +102,7 @@ clone_servent(struct servent *dest, struct servent const *src)
for (cp = src->s_aliases; *cp; ++cp)
++aliases_num;
dest->s_aliases = calloc(1, (aliases_num + 1) * sizeof(char *));
dest->s_aliases = calloc(aliases_num + 1, sizeof(char *));
ATF_REQUIRE(dest->s_aliases != NULL);
for (cp = src->s_aliases; *cp; ++cp) {
@ -177,16 +177,16 @@ sdump_servent(struct servent *serv, char *buffer, size_t buflen)
written = snprintf(buffer, buflen, "%s %d %s",
serv->s_name, ntohs(serv->s_port), serv->s_proto);
buffer += written;
if (written > buflen)
if (written > (int)buflen)
return;
buflen -= written;
if (serv->s_aliases != NULL) {
if (*(serv->s_aliases) != '\0') {
for (cp = serv->s_aliases; *cp; ++cp) {
written = snprintf(buffer, buflen, " %s",*cp);
written = snprintf(buffer, buflen, " %s", *cp);
buffer += written;
if (written > buflen)
if (written > (int)buflen)
return;
buflen -= written;
@ -300,7 +300,7 @@ servent_fill_test_data(struct servent_test_data *td)
}
static int
servent_test_correctness(struct servent *serv, void *mdata)
servent_test_correctness(struct servent *serv, void *mdata __unused)
{
printf("testing correctness with the following data:\n");
dump_servent(serv);
@ -403,14 +403,14 @@ servent_test_getservbyport(struct servent *serv_model, void *mdata)
}
static int
servent_test_getservent(struct servent *serv, void *mdata)
servent_test_getservent(struct servent *serv, void *mdata __unused)
{
/* Only correctness can be checked when doing 1-pass test for
* getservent(). */
return (servent_test_correctness(serv, NULL));
}
int
static int
run_tests(const char *snapshot_file, enum test_methods method)
{
struct servent_test_data td, td_snap, td_2pass;

View File

@ -48,8 +48,6 @@ struct usershell {
char *path;
};
static enum test_methods method = TEST_GETUSERSHELL;
DECLARE_TEST_DATA(usershell)
DECLARE_TEST_FILE_SNAPSHOT(usershell)
DECLARE_2PASS_TEST(usershell)
@ -78,7 +76,8 @@ clone_usershell(struct usershell *dest, struct usershell const *src)
}
static int
compare_usershell(struct usershell *us1, struct usershell *us2, void *mdata)
compare_usershell(struct usershell *us1, struct usershell *us2,
void *mdata __unused)
{
int rv;
@ -134,7 +133,7 @@ usershell_read_snapshot_func(struct usershell *us, char *line)
return (0);
}
int
static int
run_tests(const char *snapshot_file, enum test_methods method)
{
struct usershell_test_data td, td_snap;

View File

@ -87,8 +87,6 @@ geom_stats_open(void)
if (statsfd < 0)
return (errno);
pagesize = getpagesize();
if (pagesize == -1)
return (errno);
spp = pagesize / sizeof(struct devstat);
p = mmap(NULL, pagesize, PROT_READ, MAP_SHARED, statsfd, 0);
if (p == MAP_FAILED) {

View File

@ -56,6 +56,8 @@ ATF_TC_BODY(kvm_geterr_negative_test_NULL, tc)
ATF_REQUIRE(!errbuf_has_error(kvm_geterr(NULL)));
}
/* 1100090 was where kvm_open2(3) was introduced. */
#if __FreeBSD_version >= 1100091
ATF_TC(kvm_geterr_positive_test_error);
ATF_TC_HEAD(kvm_geterr_positive_test_error, tc)
{
@ -125,13 +127,16 @@ ATF_TC_BODY(kvm_geterr_positive_test_no_error, tc)
ATF_REQUIRE_MSG(kvm_close(kd) == 0, "kvm_close failed: %s",
strerror(errno));
}
#endif
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, kvm_geterr_negative_test_NULL);
#if __FreeBSD_version >= 1100091
ATF_TP_ADD_TC(tp, kvm_geterr_positive_test_error);
ATF_TP_ADD_TC(tp, kvm_geterr_positive_test_no_error);
#endif
return (atf_no_error());
}

View File

@ -150,7 +150,7 @@ ATF_TEST_CASE_BODY(dnvlist_get_string__default_value)
ATF_REQUIRE_EQ(strcmp(dnvlist_get_string(nvl, "hthth", "fd"), "fd"), 0);
actual_value = dnvlist_get_string(nvl, "5", "5");
ATF_REQUIRE_EQ(strcmp("5", "5"), 0);
ATF_REQUIRE_EQ(strcmp(actual_value, "5"), 0);
nvlist_destroy(nvl);
}
@ -391,6 +391,7 @@ ATF_TEST_CASE_BODY(dnvlist_take_string__empty)
ATF_REQUIRE_EQ(strcmp(actual_val, default_val), 0);
free(actual_val);
free(default_val);
nvlist_destroy(nvl);
}
@ -408,6 +409,7 @@ ATF_TEST_CASE_BODY(dnvlist_take_string__default_value)
ATF_REQUIRE_EQ(strcmp(actual_val, default_val), 0);
free(actual_val);
free(default_val);
nvlist_destroy(nvl);
}
@ -496,6 +498,7 @@ ATF_TEST_CASE_BODY(dnvlist_take_binary__present)
free(actual_val);
free(default_val);
free(value);
nvlist_destroy(nvl);
}
@ -515,6 +518,7 @@ ATF_TEST_CASE_BODY(dnvlist_take_binary__empty)
ATF_REQUIRE_EQ(memcmp(actual_val, default_val, actual_size), 0);
free(actual_val);
free(default_val);
nvlist_destroy(nvl);
}
@ -535,6 +539,7 @@ ATF_TEST_CASE_BODY(dnvlist_take_binary__default_value)
ATF_REQUIRE_EQ(memcmp(actual_val, default_val, default_size), 0);
free(actual_val);
free(default_val);
nvlist_destroy(nvl);
}

View File

@ -640,6 +640,7 @@ ATF_TEST_CASE_BODY(nvlist_unpack__duplicate_key)
nvlist_add_number(nvl, key2, 10);
packed = nvlist_pack(nvl, &size);
ATF_REQUIRE(packed != NULL);
/*
* Mangle the packed nvlist by replacing key1 with key2, creating a

View File

@ -6,7 +6,6 @@ FBSD_1.2 {
procstat_freefiles;
procstat_freeprocs;
procstat_get_pipe_info;
procstat_get_socket_info;
procstat_getfiles;
procstat_getprocs;
procstat_open_kvm;
@ -39,5 +38,6 @@ FBSD_1.5 {
procstat_get_pts_info;
procstat_get_sem_info;
procstat_get_shm_info;
procstat_get_socket_info;
procstat_get_vnode_info;
};

View File

@ -1497,6 +1497,8 @@ procstat_get_socket_info_kvm(kvm_t *kd, struct filestat *fst,
} else
sock->inp_ppcb =
(uintptr_t)inpcb.inp_ppcb;
sock->sendq = s.so_snd.sb_ccc;
sock->recvq = s.so_rcv.sb_ccc;
}
}
break;
@ -1510,6 +1512,8 @@ procstat_get_socket_info_kvm(kvm_t *kd, struct filestat *fst,
sock->so_rcv_sb_state = s.so_rcv.sb_state;
sock->so_snd_sb_state = s.so_snd.sb_state;
sock->unp_conn = (uintptr_t)unpcb.unp_conn;
sock->sendq = s.so_snd.sb_ccc;
sock->recvq = s.so_rcv.sb_ccc;
}
}
break;
@ -1556,17 +1560,22 @@ procstat_get_socket_info_sysctl(struct filestat *fst, struct sockstat *sock,
switch(sock->dom_family) {
case AF_INET:
case AF_INET6:
if (sock->proto == IPPROTO_TCP)
if (sock->proto == IPPROTO_TCP) {
sock->inp_ppcb = kif->kf_un.kf_sock.kf_sock_inpcb;
sock->sendq = kif->kf_un.kf_sock.kf_sock_sendq;
sock->recvq = kif->kf_un.kf_sock.kf_sock_recvq;
}
break;
case AF_UNIX:
if (kif->kf_un.kf_sock.kf_sock_unpconn != 0) {
sock->so_rcv_sb_state =
kif->kf_un.kf_sock.kf_sock_rcv_sb_state;
sock->so_snd_sb_state =
kif->kf_un.kf_sock.kf_sock_snd_sb_state;
sock->unp_conn =
kif->kf_un.kf_sock.kf_sock_unpconn;
sock->so_rcv_sb_state =
kif->kf_un.kf_sock.kf_sock_rcv_sb_state;
sock->so_snd_sb_state =
kif->kf_un.kf_sock.kf_sock_snd_sb_state;
sock->unp_conn =
kif->kf_un.kf_sock.kf_sock_unpconn;
sock->sendq = kif->kf_un.kf_sock.kf_sock_sendq;
sock->recvq = kif->kf_un.kf_sock.kf_sock_recvq;
}
break;
default:

View File

@ -157,6 +157,8 @@ struct sockstat {
struct sockaddr_storage sa_peer; /* Peer address. */
int type;
char dname[32];
unsigned int sendq;
unsigned int recvq;
};
STAILQ_HEAD(filestat_list, filestat);

View File

@ -60,12 +60,29 @@ struct freebsd11_shmstat {
uint16_t mode;
};
struct freebsd11_sockstat {
uint64_t inp_ppcb;
uint64_t so_addr;
uint64_t so_pcb;
uint64_t unp_conn;
int dom_family;
int proto;
int so_rcv_sb_state;
int so_snd_sb_state;
struct sockaddr_storage sa_local; /* Socket address. */
struct sockaddr_storage sa_peer; /* Peer address. */
int type;
char dname[32];
};
int freebsd11_procstat_get_pts_info(struct procstat *procstat,
struct filestat *fst, struct freebsd11_ptsstat *pts, char *errbuf);
int freebsd11_procstat_get_sem_info(struct procstat *procstat,
struct filestat *fst, struct freebsd11_semstat *sem, char *errbuf);
int freebsd11_procstat_get_shm_info(struct procstat *procstat,
struct filestat *fst, struct freebsd11_shmstat *shm, char *errbuf);
int freebsd11_procstat_get_socket_info(struct procstat *procstat,
struct filestat *fst, struct freebsd11_sockstat *sock, char *errbuf);
int freebsd11_procstat_get_vnode_info(struct procstat *procstat,
struct filestat *fst, struct freebsd11_vnstat *vn, char *errbuf);
@ -115,6 +132,31 @@ freebsd11_procstat_get_shm_info(struct procstat *procstat,
return (0);
}
int
freebsd11_procstat_get_socket_info(struct procstat *procstat, struct filestat *fst,
struct freebsd11_sockstat *sock_compat, char *errbuf)
{
struct sockstat sock;
int r;
r = procstat_get_socket_info(procstat, fst, &sock, errbuf);
if (r != 0)
return (r);
sock_compat->inp_ppcb = sock.inp_ppcb;
sock_compat->so_addr = sock.so_addr;
sock_compat->so_pcb = sock.so_pcb;
sock_compat->unp_conn = sock.unp_conn;
sock_compat->dom_family = sock.dom_family;
sock_compat->proto = sock.proto;
sock_compat->so_rcv_sb_state = sock.so_rcv_sb_state;
sock_compat->so_snd_sb_state = sock.so_snd_sb_state;
sock_compat->sa_local = sock.sa_local;
sock_compat->sa_peer = sock.sa_peer;
sock_compat->type = sock.type;
memcpy(sock_compat->dname, sock.dname, sizeof(sock.dname));
return (0);
}
int
freebsd11_procstat_get_vnode_info(struct procstat *procstat,
struct filestat *fst, struct freebsd11_vnstat *vn_compat, char *errbuf)
@ -138,6 +180,8 @@ freebsd11_procstat_get_vnode_info(struct procstat *procstat,
}
__sym_compat(procstat_get_pts_info, freebsd11_procstat_get_pts_info, FBSD_1.2);
__sym_compat(procstat_get_socket_info, freebsd11_procstat_get_socket_info,
FBSD_1.2);
__sym_compat(procstat_get_vnode_info, freebsd11_procstat_get_vnode_info,
FBSD_1.2);
__sym_compat(procstat_get_sem_info, freebsd11_procstat_get_sem_info, FBSD_1.3);

View File

@ -93,9 +93,38 @@ struct in_addr dhcp_serverip;
struct bootp *bootp_response;
size_t bootp_response_size;
static void
bootp_fill_request(unsigned char *bp_vend)
{
/*
* We are booting from PXE, we want to send the string
* 'PXEClient' to the DHCP server so you have the option of
* only responding to PXE aware dhcp requests.
*/
bp_vend[0] = TAG_CLASSID;
bp_vend[1] = 9;
bcopy("PXEClient", &bp_vend[2], 9);
bp_vend[11] = TAG_USER_CLASS;
/* len of each user class + number of user class */
bp_vend[12] = 8;
/* len of the first user class */
bp_vend[13] = 7;
bcopy("FreeBSD", &bp_vend[14], 7);
bp_vend[21] = TAG_PARAM_REQ;
bp_vend[22] = 7;
bp_vend[23] = TAG_ROOTPATH;
bp_vend[24] = TAG_HOSTNAME;
bp_vend[25] = TAG_SWAPSERVER;
bp_vend[26] = TAG_GATEWAY;
bp_vend[27] = TAG_SUBNET_MASK;
bp_vend[28] = TAG_INTF_MTU;
bp_vend[29] = TAG_SERVERID;
bp_vend[30] = TAG_END;
}
/* Fetch required bootp infomation */
void
bootp(int sock, int flag)
bootp(int sock)
{
void *pkt;
struct iodesc *d;
@ -136,28 +165,8 @@ bootp(int sock, int flag)
bp->bp_vend[4] = TAG_DHCP_MSGTYPE;
bp->bp_vend[5] = 1;
bp->bp_vend[6] = DHCPDISCOVER;
bootp_fill_request(&bp->bp_vend[7]);
/*
* If we are booting from PXE, we want to send the string
* 'PXEClient' to the DHCP server so you have the option of
* only responding to PXE aware dhcp requests.
*/
if (flag & BOOTP_PXE) {
bp->bp_vend[7] = TAG_CLASSID;
bp->bp_vend[8] = 9;
bcopy("PXEClient", &bp->bp_vend[9], 9);
bp->bp_vend[18] = TAG_PARAM_REQ;
bp->bp_vend[19] = 7;
bp->bp_vend[20] = TAG_ROOTPATH;
bp->bp_vend[21] = TAG_HOSTNAME;
bp->bp_vend[22] = TAG_SWAPSERVER;
bp->bp_vend[23] = TAG_GATEWAY;
bp->bp_vend[24] = TAG_SUBNET_MASK;
bp->bp_vend[25] = TAG_INTF_MTU;
bp->bp_vend[26] = TAG_SERVERID;
bp->bp_vend[27] = TAG_END;
} else
bp->bp_vend[7] = TAG_END;
#else
bp->bp_vend[4] = TAG_END;
#endif
@ -193,13 +202,7 @@ bootp(int sock, int flag)
bp->bp_vend[20] = 4;
leasetime = htonl(300);
bcopy(&leasetime, &bp->bp_vend[21], 4);
if (flag & BOOTP_PXE) {
bp->bp_vend[25] = TAG_CLASSID;
bp->bp_vend[26] = 9;
bcopy("PXEClient", &bp->bp_vend[27], 9);
bp->bp_vend[36] = TAG_END;
} else
bp->bp_vend[25] = TAG_END;
bootp_fill_request(&bp->bp_vend[25]);
expected_dhcpmsgtype = DHCPACK;

View File

@ -108,6 +108,7 @@ struct bootp {
#define TAG_T2 ((unsigned char) 59)
#define TAG_CLASSID ((unsigned char) 60)
#define TAG_CLIENTID ((unsigned char) 61)
#define TAG_USER_CLASS ((unsigned char) 77)
#endif
#define TAG_END ((unsigned char) 255)
@ -122,12 +123,6 @@ struct bootp {
#define DHCPRELEASE 7
#endif
/*
* bootp flags
*/
#define BOOTP_NONE 0x0000 /* No flags */
#define BOOTP_PXE 0x0001 /* Booting from PXE. */
/*
* "vendor" data permitted for CMU bootp clients.
*/

View File

@ -119,7 +119,7 @@ ssize_t sendrecv(struct iodesc *,
void **, void **);
/* bootp/DHCP */
void bootp(int, int);
void bootp(int);
/* Utilities: */
char *ether_sprintf(u_char *);

View File

@ -73,7 +73,8 @@ COMMON_SRCS= b_exp.c b_log.c b_tgamma.c \
s_nexttowardf.c s_remquo.c s_remquof.c \
s_rint.c s_rintf.c s_round.c s_roundf.c \
s_scalbln.c s_scalbn.c s_scalbnf.c s_signbit.c \
s_signgam.c s_significand.c s_significandf.c s_sin.c s_sinf.c \
s_signgam.c s_significand.c s_significandf.c s_sin.c \
s_sincos.c s_sincosf.c s_sinf.c \
s_tan.c s_tanf.c s_tanh.c s_tanhf.c s_tgammaf.c s_trunc.c s_truncf.c \
w_cabs.c w_cabsf.c w_drem.c w_dremf.c
@ -104,7 +105,8 @@ COMMON_SRCS+= catrigl.c \
s_csqrtl.c s_erfl.c s_exp2l.c s_expl.c s_floorl.c s_fmal.c \
s_fmaxl.c s_fminl.c s_frexpl.c s_logbl.c s_logl.c s_nanl.c \
s_nextafterl.c s_nexttoward.c s_remquol.c s_rintl.c s_roundl.c \
s_scalbnl.c s_sinl.c s_tanhl.c s_tanl.c s_truncl.c w_cabsl.c
s_scalbnl.c s_sinl.c s_sincosl.c \
s_tanhl.c s_tanl.c s_truncl.c w_cabsl.c
.endif
# C99 complex functions
@ -137,7 +139,8 @@ MAN= acos.3 acosh.3 asin.3 asinh.3 atan.3 atan2.3 atanh.3 \
fma.3 fmax.3 fmod.3 hypot.3 ieee.3 ieee_test.3 ilogb.3 j0.3 \
lgamma.3 log.3 lrint.3 lround.3 math.3 nan.3 \
nextafter.3 remainder.3 rint.3 \
round.3 scalbn.3 signbit.3 sin.3 sinh.3 sqrt.3 tan.3 tanh.3 trunc.3 \
round.3 scalbn.3 signbit.3 sin.3 sincos.3 \
sinh.3 sqrt.3 tan.3 tanh.3 trunc.3 \
complex.3
MLINKS+=acos.3 acosf.3 acos.3 acosl.3
@ -215,6 +218,7 @@ MLINKS+=round.3 roundf.3 round.3 roundl.3
MLINKS+=scalbn.3 scalbln.3 scalbn.3 scalblnf.3 scalbn.3 scalblnl.3
MLINKS+=scalbn.3 scalbnf.3 scalbn.3 scalbnl.3
MLINKS+=sin.3 sinf.3 sin.3 sinl.3
MLINKS+=sincos.3 sincosf.3 sin.3 sincosl.3
MLINKS+=sinh.3 sinhf.3 sinh.3 sinhl.3
MLINKS+=sqrt.3 cbrt.3 sqrt.3 cbrtf.3 sqrt.3 cbrtl.3 sqrt.3 sqrtf.3 \
sqrt.3 sqrtl.3

View File

@ -294,4 +294,7 @@ FBSD_1.5 {
casinl;
catanl;
catanhl;
sincos;
sincosf;
sincosl;
};

82
lib/msun/man/sincos.3 Normal file
View File

@ -0,0 +1,82 @@
.\" Copyright (c) 2011 Steven G. Kargl.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $FreeBSD$
.\"
.Dd March 12, 2011
.Dt SINCOS 3
.Os
.Sh NAME
.Nm sincos ,
.Nm sincosf ,
.Nm sincosl
.Nd sine and cosine functions
.Sh LIBRARY
.Lb libm
.Sh SYNOPSIS
.In math.h
.Ft void
.Fn sincos "double x" "double *s" "double *c"
.Ft void
.Fn sincosf "float x" "float *s" "float *c"
.Ft void
.Fn sincosl "long double x" "long double *s" "long double *c"
.Sh DESCRIPTION
The
.Fn sincos ,
.Fn sincosf ,
and
.Fn sincosl
functions compute the sine and cosine of
.Fa x .
Using these functions allows argument reduction to occur only
once instead of twice with individual invocations of
.Fn sin
and
.Fn cos .
Like
.Fn sin
and
.Fn cos ,
a large magnitude argument may yield a result with little
or no significance.
.Sh RETURN VALUES
Upon returning from
.Fn sincos ,
.Fn sincosf ,
and
.Fn sincosl ,
the memory pointed to by
.Ar "*s"
and
.Ar "*c"
are assigned the values of sine and cosine, respectively.
.Sh SEE ALSO
.Xr cos 3 ,
.Xr sin 3 ,
.Sh HISTORY
These functions were added to
.Fx 9.0
to aid in writing various complex function contained in
.St -isoC-99 .

52
lib/msun/src/k_sincos.h Normal file
View File

@ -0,0 +1,52 @@
/*-
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*
* k_sin.c and k_cos.c merged by Steven G. Kargl.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
static const double
S1 = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */
S2 = 8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */
S3 = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */
S4 = 2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */
S5 = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */
S6 = 1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */
static const double
C1 = 4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */
C2 = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */
C3 = 2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */
C4 = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */
C5 = 2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */
C6 = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */
static inline void
__kernel_sincos(double x, double y, int iy, double *sn, double *cs)
{
double hz, r, v, w, z;
z = x * x;
w = z * z;
r = S2 + z * (S3 + z * S4) + z * w * (S5 + z * S6);
v = z * x;
if (iy == 0)
*sn = x + v * (S1 + z * r);
else
*sn = x - ((z * (y / 2 - v * r) - y) - v * S1);
r = z * (C1 + z * (C2 + z * C3)) + w * w * (C4 + z * (C5 + z * C6));
hz = z / 2;
w = 1 - hz;
*cs = w + (((1 - w) - hz) + (z * r - x * y));
}

43
lib/msun/src/k_sincosf.h Normal file
View File

@ -0,0 +1,43 @@
/*-
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*
* k_sinf.c and k_cosf.c merged by Steven G. Kargl.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/* |sin(x)/x - s(x)| < 2**-37.5 (~[-4.89e-12, 4.824e-12]). */
static const double
S1 = -0x15555554cbac77.0p-55, /* -0.166666666416265235595 */
S2 = 0x111110896efbb2.0p-59, /* 0.0083333293858894631756 */
S3 = -0x1a00f9e2cae774.0p-65, /* -0.000198393348360966317347 */
S4 = 0x16cd878c3b46a7.0p-71; /* 0.0000027183114939898219064 */
/* |cos(x) - c(x)| < 2**-34.1 (~[-5.37e-11, 5.295e-11]). */
static const double
C0 = -0x1ffffffd0c5e81.0p-54, /* -0.499999997251031003120 */
C1 = 0x155553e1053a42.0p-57, /* 0.0416666233237390631894 */
C2 = -0x16c087e80f1e27.0p-62, /* -0.00138867637746099294692 */
C3 = 0x199342e0ee5069.0p-68; /* 0.0000243904487962774090654 */
static inline void
__kernel_sincosdf(double x, float *sn, float *cs)
{
double r, s, w, z;
z = x * x;
w = z * z;
r = S3 + z * S4;
s = z * x;
*sn = (x + s * (S1 + z * S2)) + s * w * r;
r = C2 + z * C3;
*cs = ((1 + z * C0) + w * C1) + (w * z) * r;
}

134
lib/msun/src/k_sincosl.h Normal file
View File

@ -0,0 +1,134 @@
/*-
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
* Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*
* k_sinl.c and k_cosl.c merged by Steven G. Kargl
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#if LDBL_MANT_DIG == 64 /* ld80 version of k_sincosl.c. */
#if defined(__amd64__) || defined(__i386__)
/* Long double constants are slow on these arches, and broken on i386. */
static const volatile double
C1hi = 0.041666666666666664, /* 0x15555555555555.0p-57 */
C1lo = 2.2598839032744733e-18, /* 0x14d80000000000.0p-111 */
S1hi = -0.16666666666666666, /* -0x15555555555555.0p-55 */
S1lo = -9.2563760475949941e-18; /* -0x15580000000000.0p-109 */
#define S1 ((long double)S1hi + S1lo)
#define C1 ((long double)C1hi + C1lo)
#else
static const long double
C1 = 0.0416666666666666666136L; /* 0xaaaaaaaaaaaaaa9b.0p-68 */
S1 = -0.166666666666666666671L, /* -0xaaaaaaaaaaaaaaab.0p-66 */
#endif
static const double
C2 = -0.0013888888888888874, /* -0x16c16c16c16c10.0p-62 */
C3 = 0.000024801587301571716, /* 0x1a01a01a018e22.0p-68 */
C4 = -0.00000027557319215507120, /* -0x127e4fb7602f22.0p-74 */
C5 = 0.0000000020876754400407278, /* 0x11eed8caaeccf1.0p-81 */
C6 = -1.1470297442401303e-11, /* -0x19393412bd1529.0p-89 */
C7 = 4.7383039476436467e-14, /* 0x1aac9d9af5c43e.0p-97 */
S2 = 0.0083333333333333332, /* 0x11111111111111.0p-59 */
S3 = -0.00019841269841269427, /* -0x1a01a01a019f81.0p-65 */
S4 = 0.0000027557319223597490, /* 0x171de3a55560f7.0p-71 */
S5 = -0.000000025052108218074604, /* -0x1ae64564f16cad.0p-78 */
S6 = 1.6059006598854211e-10, /* 0x161242b90243b5.0p-85 */
S7 = -7.6429779983024564e-13, /* -0x1ae42ebd1b2e00.0p-93 */
S8 = 2.6174587166648325e-15; /* 0x179372ea0b3f64.0p-101 */
static inline void
__kernel_sincosl(long double x, long double y, int iy, long double *sn,
long double *cs)
{
long double hz, r, v, w, z;
z = x * x;
v = z * x;
/*
* XXX Replace Horner scheme with an algorithm suitable for CPUs
* with more complex pipelines.
*/
r = S2 + z * (S3 + z * (S4 + z * (S5 + z * (S6 + z * (S7 + z * S8)))));
if (iy == 0)
*sn = x + v * (S1 + z * r);
else
*sn = x - ((z * (y / 2 - v * r) - y) - v * S1);
hz = z / 2;
w = 1 - hz;
r = z * (C1 + z * (C2 + z * (C3 + z * (C4 + z * (C5 + z * (C6 +
z * C7))))));
*cs = w + (((1 - w) - hz) + (z * r - x * y));
}
#elif LDBL_MANT_DIG == 113 /* ld128 version of k_sincosl.c. */
static const long double
C1 = 0.04166666666666666666666666666666658424671L,
C2 = -0.001388888888888888888888888888863490893732L,
C3 = 0.00002480158730158730158730158600795304914210L,
C4 = -0.2755731922398589065255474947078934284324e-6L,
C5 = 0.2087675698786809897659225313136400793948e-8L,
C6 = -0.1147074559772972315817149986812031204775e-10L,
C7 = 0.4779477332386808976875457937252120293400e-13L,
S1 = -0.16666666666666666666666666666666666606732416116558L,
S2 = 0.0083333333333333333333333333333331135404851288270047L,
S3 = -0.00019841269841269841269841269839935785325638310428717L,
S4 = 0.27557319223985890652557316053039946268333231205686e-5L,
S5 = -0.25052108385441718775048214826384312253862930064745e-7L,
S6 = 0.16059043836821614596571832194524392581082444805729e-9L,
S7 = -0.76471637318198151807063387954939213287488216303768e-12L,
S8 = 0.28114572543451292625024967174638477283187397621303e-14L;
static const double
C8 = -0.1561920696721507929516718307820958119868e-15,
C9 = 0.4110317413744594971475941557607804508039e-18,
C10 = -0.8896592467191938803288521958313920156409e-21,
C11 = 0.1601061435794535138244346256065192782581e-23,
S9 = -0.82206352458348947812512122163446202498005154296863e-17,
S10 = 0.19572940011906109418080609928334380560135358385256e-19,
S11 = -0.38680813379701966970673724299207480965452616911420e-22,
S12 = 0.64038150078671872796678569586315881020659912139412e-25;
static inline void
__kernel_sincosl(long double x, long double y, int iy, long double *sn,
long double *cs)
{
long double hz, r, v, w, z;
z = x * x;
v = z * x;
/*
* XXX Replace Horner scheme with an algorithm suitable for CPUs
* with more complex pipelines.
*/
r = S2 + z * (S3 + z * (S4 + z * (S5 + z * (S6 + z * (S7 + z * (S8 +
z * (S9 + z * (S10 + z * (S11 + z * S12)))))))));
if (iy == 0)
*sn = x + v * (S1 + z * r);
else
*cs = x - ((z * (y / 2 - v * r) - y) - v * S1);
hz = z / 2;
w = 1 - hz;
r = z * (C1 + z * (C2 + z * (C3 + z * (C4 + z * (C5 + z * (C6 +
z * (C7 + z * (C8 + z * (C9 + z * (C10 + z * C11))))))))));
*cs = w + (((1 - w) - hz) + (z * r - x * y));
}
#else
#error "Unsupported long double format"
#endif

View File

@ -500,6 +500,9 @@ long double truncl(long double);
#if __BSD_VISIBLE
long double lgammal_r(long double, int *);
void sincos(double, double *, double *);
void sincosf(float, float *, float *);
void sincosl(long double, long double *, long double *);
#endif
__END_DECLS

View File

@ -306,9 +306,21 @@ do { \
fpsetprec(__oprec); \
RETURNF(__retval); \
} while (0)
#define ENTERV() \
fp_prec_t __oprec; \
\
if ((__oprec = fpgetprec()) != FP_PE) \
fpsetprec(FP_PE)
#define RETURNV() do { \
if (__oprec != FP_PE) \
fpsetprec(__oprec); \
return; \
} while (0)
#else
#define ENTERI(x)
#define ENTERI()
#define RETURNI(x) RETURNF(x)
#define ENTERV()
#define RETURNV() return
#endif
/* Default return statement if hack*_t() is not used. */

80
lib/msun/src/s_sincos.c Normal file
View File

@ -0,0 +1,80 @@
/*-
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*
* s_sin.c and s_cos.c merged by Steven G. Kargl. Descriptions of the
* algorithms are contained in the original files.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <float.h>
#include "math.h"
#define INLINE_REM_PIO2
#include "math_private.h"
#include "e_rem_pio2.c"
#include "k_sincos.h"
void
sincos(double x, double *sn, double *cs)
{
double y[2];
int32_t n, ix;
/* High word of x. */
GET_HIGH_WORD(ix, x);
/* |x| ~< pi/4 */
ix &= 0x7fffffff;
if (ix <= 0x3fe921fb) {
if (ix < 0x3e400000) { /* |x| < 2**-27 */
if ((int)x == 0) { /* Generate inexact. */
*sn = x;
*cs = 1;
return;
}
}
__kernel_sincos(x, 0, 0, sn, cs);
return;
}
/* If x = Inf or NaN, then sin(x) = NaN and cos(x) = NaN. */
if (ix >= 0x7ff00000) {
*sn = x - x;
*cs = x - x;
return;
}
/* Argument reduction. */
n = __ieee754_rem_pio2(x, y);
switch(n & 3) {
case 0:
__kernel_sincos(y[0], y[1], 1, sn, cs);
break;
case 1:
__kernel_sincos(y[0], y[1], 1, cs, sn);
*cs = -*cs;
break;
case 2:
__kernel_sincos(y[0], y[1], 1, sn, cs);
*sn = -*sn;
*cs = -*cs;
break;
default:
__kernel_sincos(y[0], y[1], 1, cs, sn);
*sn = -*sn;
}
}
#if (LDBL_MANT_DIG == 53)
__weak_reference(sincos, sincosl);
#endif

126
lib/msun/src/s_sincosf.c Normal file
View File

@ -0,0 +1,126 @@
/*-
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* s_sincosf.c -- float version of s_sincos.c.
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
* Optimized by Bruce D. Evans.
* Merged s_sinf.c and s_cosf.c by Steven G. Kargl.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <float.h>
#include "math.h"
#define INLINE_REM_PIO2F
#include "math_private.h"
#include "e_rem_pio2f.c"
#include "k_sincosf.h"
/* Small multiples of pi/2 rounded to double precision. */
static const double
p1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */
p2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */
p3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */
p4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */
void
sincosf(float x, float *sn, float *cs)
{
float c, s;
double y;
int32_t n, hx, ix;
GET_FLOAT_WORD(hx, x);
ix = hx & 0x7fffffff;
if (ix <= 0x3f490fda) { /* |x| ~<= pi/4 */
if (ix < 0x39800000) { /* |x| < 2**-12 */
if ((int)x == 0) {
*sn = x; /* x with inexact if x != 0 */
*cs = 1;
return;
}
}
__kernel_sincosdf(x, sn, cs);
return;
}
if (ix <= 0x407b53d1) { /* |x| ~<= 5*pi/4 */
if (ix <= 0x4016cbe3) { /* |x| ~<= 3pi/4 */
if (hx > 0) {
__kernel_sincosdf(x - p1pio2, cs, sn);
*cs = -*cs;
} else {
__kernel_sincosdf(x + p1pio2, cs, sn);
*sn = -*sn;
}
} else {
if (hx > 0)
__kernel_sincosdf(x - p2pio2, sn, cs);
else
__kernel_sincosdf(x + p2pio2, sn, cs);
*sn = -*sn;
*cs = -*cs;
}
return;
}
if (ix <= 0x40e231d5) { /* |x| ~<= 9*pi/4 */
if (ix <= 0x40afeddf) { /* |x| ~<= 7*pi/4 */
if (hx > 0) {
__kernel_sincosdf(x - p3pio2, cs, sn);
*sn = -*sn;
} else {
__kernel_sincosdf(x + p3pio2, cs, sn);
*cs = -*cs;
}
} else {
if (hx > 0)
__kernel_sincosdf(x - p4pio2, sn, cs);
else
__kernel_sincosdf(x + p4pio2, sn, cs);
}
return;
}
/* If x = Inf or NaN, then sin(x) = NaN and cos(x) = NaN. */
if (ix >= 0x7f800000) {
*sn = x - x;
*cs = x - x;
return;
}
/* Argument reduction. */
n = __ieee754_rem_pio2f(x, &y);
__kernel_sincosdf(y, &s, &c);
switch(n & 3) {
case 0:
*sn = s;
*cs = c;
break;
case 1:
*sn = c;
*cs = -s;
break;
case 2:
*sn = -s;
*cs = -c;
break;
default:
*sn = -c;
*cs = s;
}
}

105
lib/msun/src/s_sincosl.c Normal file
View File

@ -0,0 +1,105 @@
/*-
* Copyright (c) 2007, 2010-2013 Steven G. Kargl
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice unmodified, this list of conditions, and the following
* disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* s_sinl.c and s_cosl.c merged by Steven G. Kargl.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <float.h>
#ifdef __i386__
#include <ieeefp.h>
#endif
#include "math.h"
#include "math_private.h"
#include "k_sincosl.h"
#if LDBL_MANT_DIG == 64
#include "../ld80/e_rem_pio2l.h"
#elif LDBL_MANT_DIG == 113
#include "../ld128/e_rem_pio2l.h"
#else
#error "Unsupported long double format"
#endif
void
sincosl(long double x, long double *sn, long double *cs)
{
union IEEEl2bits z;
int e0, sgn;
long double y[2];
z.e = x;
sgn = z.bits.sign;
z.bits.sign = 0;
ENTERV();
/* Optimize the case where x is already within range. */
if (z.e < M_PI_4) {
/*
* If x = +-0 or x is a subnormal number, then sin(x) = x and
* cos(x) = 1.
*/
if (z.bits.exp == 0) {
*sn = x;
*cs = 1;
} else
__kernel_sincosl(x, 0, 0, sn, cs);
RETURNV();
}
/* If x = NaN or Inf, then sin(x) and cos(x) are NaN. */
if (z.bits.exp == 32767) {
*sn = x - x;
*cs = x - x;
RETURNV();
}
/* Range reduction. */
e0 = __ieee754_rem_pio2l(x, y);
switch (e0 & 3) {
case 0:
__kernel_sincosl(y[0], y[1], 1, sn, cs);
break;
case 1:
__kernel_sincosl(y[0], y[1], 1, cs, sn);
*cs = -*cs;
break;
case 2:
__kernel_sincosl(y[0], y[1], 1, sn, cs);
*sn = -*sn;
*cs = -*cs;
break;
default:
__kernel_sincosl(y[0], y[1], 1, cs, sn);
*sn = -*sn;
}
RETURNV();
}

View File

@ -498,11 +498,12 @@ main(void)
printf("ok %d # SKIP testcase fails assertion on "
"amd64\n", j);
continue;
#endif
#else
printf("rmode = %d\n", rmodes[i]);
fesetround(rmodes[i]);
test_infinities();
printf("ok %d - fma infinities\n", j);
#endif
}
fesetround(FE_TONEAREST);

View File

@ -137,7 +137,7 @@ run_log2_tests(void)
* We should insist that log2() return exactly the correct
* result and not raise an inexact exception for powers of 2.
*/
feclearexcept(FE_ALL_EXCEPT);
assert(feclearexcept(FE_ALL_EXCEPT) == 0);
for (i = FLT_MIN_EXP - FLT_MANT_DIG; i < FLT_MAX_EXP; i++) {
assert(log2f(ldexpf(1.0, i)) == i);
assert(fetestexcept(ALL_STD_EXCEPT) == 0);

View File

@ -28,7 +28,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd March 16, 2017
.Dd May 20, 2017
.Dt RTLD 1
.Os
.Sh NAME
@ -60,10 +60,11 @@ This is useful for C++ libraries that contain static constructors.
.Pp
When resolving dependencies for the loaded objects,
.Nm
may be allowed to translate dynamic token strings in rpath and soname
by setting
translates dynamic token strings in rpath and soname.
If the
.Fl "z origin"
option of the static linker
option of the static linker was set when linking the binary,
the token expansion is performed at the object load time, see
.Xr ld 1 .
The following strings are recognized now:
.Bl -tag -width ".Pa $PLATFORM"
@ -282,6 +283,77 @@ instead of postponing it until required.
Normally, the filtees are opened at the time of the first symbol resolution
from the filter object.
.El
.Sh DIRECT EXECUTION MODE
.Nm
is typically used implicitly, loaded by the kernel as requested by the
.Dv PT_INTERP
program header of the executed binary.
.Fx
also supports a direct execution mode for the dynamic linker.
In this mode, the user explicitly executes
.Nm
and provides the path of the program to be linked and executed as
an argument.
This mode allows use of a non-standard dynamic linker for a program
activation without changing the binary or without changing
the installed dynamic linker.
Execution options may be specified.
.Pp
The syntax of the direct invocation is
.Bd -ragged -offset indent
.Pa /libexec/ld-elf.so.1
.Op Fl f Ar fd
.Op Fl p
.Op Fl -
.Pa image_path
.Op Ar image arguments
.Ed
.Pp
The options are as follows:
.Bl -tag -width indent
.It Fl f Ar fd
File descriptor
.Ar fd
references the binary to be activated by
.Nm .
It must already be opened in the process when executing
.Nm .
If this option is specified,
.Ar image_path
is only used to provide the
.Va argv[0]
value to the program.
.It Fl p
If the
.Pa image_path
argument specifies a name which does not contain a slash
.Dq Li /
character,
.Nm
uses the search path provided by the environment variable
.Dv PATH
to find the binary to execute.
.It Fl -
Ends the
.Nm
options.
The argument following
.Fl -
is interpreted as the path of binary to execute.
.El
.Pp
To conform to user expectation to not break some naively restricted
execution environments, in the direct execution mode
.Nm
emulates verification of the binary execute permission
for current user.
The verification only uses Unix
.Dv DACs ,
ignores
.Dv ACLs
and is racy by its nature.
The environments which rely on such restrictions are weak
and breakable on its own.
.Sh FILES
.Bl -tag -width ".Pa /var/run/ld-elf32.so.hints" -compact
.It Pa /var/run/ld-elf.so.hints

View File

@ -4,7 +4,7 @@
PACKAGE=runtime
PROG= mount
SRCS= mount.c mount_fs.c getmntopts.c vfslist.c
MAN= mount.8 mount.conf.8
MAN= mount.8
# We do NOT install the getmntopts.3 man page.
LIBADD= util

View File

@ -350,6 +350,7 @@ requirement has not been adhered to.
.Xr ddb 4 ,
.Xr boot.config 5 ,
.Xr make.conf 5 ,
.Xr mount.conf 5 ,
.Xr ttys 5 ,
.Xr boot0cfg 8 ,
.Xr btxld 8 ,

View File

@ -427,6 +427,7 @@ MAN= aac.4 \
ral.4 \
random.4 \
rc.4 \
rctl.4 \
re.4 \
rgephy.4 \
rights.4 \

View File

@ -25,7 +25,7 @@
.\" SUCH DAMAGE.
.\"
.\" $FreeBSD$
.Dd March 29, 2017
.Dd May 28, 2017
.Dt CFISCSI 4
.Os
.Sh NAME
@ -50,9 +50,15 @@ cfiscsi_load="YES"
.Sh DESCRIPTION
The
.Nm
subsystem provides iSCSI target device emulation via
subsystem provides the kernel component of an iSCSI target.
The target is the iSCSI server, providing LUNs backed by local files
and volumes to remote initiators.
The userspace component is provided by
.Xr ctld 8 .
.Nm
is implemented as a
.Xr ctl 4
and
frontend and uses infrastructure provided by
.Xr iscsi 4 .
.Sh SYSCTL VARIABLES
The following variables are available as both
@ -80,7 +86,9 @@ Defaults to 5.
.El
.Sh SEE ALSO
.Xr ctl 4 ,
.Xr iscsi 4
.Xr iscsi 4 ,
.Xr ctl.conf 5 ,
.Xr ctld 8
.Sh HISTORY
The
.Nm

View File

@ -23,7 +23,7 @@
.\" SUCH DAMAGE.
.\"
.\" $FreeBSD$
.Dd July 11, 2015
.Dd May 28, 2017
.Dt ISCSI 4
.Os
.Sh NAME
@ -46,18 +46,14 @@ iscsi_load="YES"
.Sh DESCRIPTION
The
.Nm
subsystem provides the kernel component of an iSCSI initiator.
subsystem provides the kernel component of an iSCSI initiator,
responsible for implementing the Full Feature Phase of the iSCSI protocol.
The initiator is the iSCSI client, which connects to an iSCSI target,
providing local access to a remote block device.
The userland component is provided by
.Xr iscsid 8
and both the kernel and userland are configured using
.Xr iscsictl 8 .
The
.Nm
subsystem is responsible for implementing the
.Qq Full Feature Phase
of the iSCSI protocol.
.Sh SYSCTL VARIABLES
The following variables are available as both
.Xr sysctl 8

74
share/man/man4/rctl.4 Normal file
View File

@ -0,0 +1,74 @@
.\" Copyright (c) 2017 Edward Tomasz Napierala
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $FreeBSD$
.Dd May 28, 2017
.Dt RCTL 4
.Os
.Sh NAME
.Nm rctl
.Nd resource limits
.Sh SYNOPSIS
To compile this driver into the kernel,
place the following line in the
kernel configuration file:
.Bd -ragged -offset indent
.Cd "options RACCT"
.Cd "options RCTL"
.Ed
.Sh DESCRIPTION
The
.Nm
subsystem provides a flexible resource limits mechanism,
controlled by a set of rules that can be added or removed at runtime
using the
.Xr rctl 8
management utility.
.Sh LOADER TUNABLES
Tunables can be set at the
.Xr loader 8
prompt, or
.Xr loader.conf 5 .
.Bl -tag -width indent
.It Va kern.racct.enable: No 1
Enable
.Nm .
This defaults to 1, unless
.Cd "options RACCT_DEFAULT_TO_DISABLED"
is set in the kernel configuration file.
.El
.Sh SEE ALSO
.Xr rctl.conf 5 ,
.Xr rctl 8
.Sh HISTORY
The
.Nm
subsystem first appeared in
.Fx 9.0 .
.Sh AUTHORS
The
.Nm
subsystem was developed by
.An Edward Tomasz Napierala Aq Mt trasz@FreeBSD.org
under sponsorship from the FreeBSD Foundation.

View File

@ -40,6 +40,7 @@ MAN= acct.5 \
make.conf.5 \
moduli.5 \
motd.5 \
mount.conf.5 \
mqueuefs.5 \
msdosfs.5 \
networks.5 \

View File

@ -27,7 +27,7 @@
.\"
.\"
.Dd October 17, 2013
.Dt MOUNT.CONF 8
.Dt MOUNT.CONF 5
.Os
.Sh NAME
.Nm mount.conf
@ -52,7 +52,7 @@ The logic for this is in
.Fn vfs_mountroot_conf0 .
.It
The kernel will first mount
.Xr devfs 8
.Xr devfs 5
as the root file system.
.It
Next, the kernel will parse the in-memory config file created in step 1
@ -224,7 +224,7 @@ For each root file system which is mounted, a
directory
.Em must
exist so that the root mount logic can properly re-mount
.Xr devfs 8 .
.Xr devfs 5 .
If this directory does not exist, the system
may hang during the bootup process.
.Sh SEE ALSO

View File

@ -16,6 +16,25 @@ __<bsd.init.mk>__:
.include <bsd.own.mk>
.MAIN: all
# Handle INSTALL_AS_USER here to maximize the chance that
# it has final authority over fooOWN and fooGRP.
.if ${MK_INSTALL_AS_USER} != "no"
.if !defined(_uid)
_uid!= id -u
.export _uid
.endif
.if ${_uid} != 0
.if !defined(_gid)
_gid!= id -g
.export _gid
.endif
.for x in BIN CONF DOC DTB INFO KMOD LIB MAN NLS SHARE
$xOWN= ${_uid}
$xGRP= ${_gid}
.endfor
.endif
.endif
# Some targets need to know when something may build. This is used to
# optimize targets that are only needed when building something, such as
# (not) reading in depend files. For DIRDEPS_BUILD, it will only calculate

View File

@ -135,31 +135,6 @@ CTFCONVERT_CMD=
CTFCONVERT_CMD= @:
.endif
.if ${MK_INSTALL_AS_USER} != "no"
.if !defined(_uid)
_uid!= id -u
.export _uid
.endif
.if ${_uid} != 0
.if !defined(USER)
# Avoid exporting USER
.if !defined(_USER)
_USER!= id -un
.export _USER
.endif
USER= ${_USER}
.endif
.if !defined(_gid)
_gid!= id -g
.export _gid
.endif
.for x in BIN CONF DOC DTB INFO KMOD LIB MAN NLS SHARE
$xOWN= ${USER}
$xGRP= ${_gid}
.endfor
.endif
.endif
.endif # !_WITHOUT_SRCCONF
# Binaries

View File

@ -101,9 +101,6 @@ typedef struct {
/*
* Miscellaneous
*/
#define LINUX_NAME_MAX 255
#define LINUX_CTL_MAXNAME 10
#define LINUX_AT_COUNT 19 /* Count of used aux entry types. */
struct l___sysctl_args
@ -117,11 +114,6 @@ struct l___sysctl_args
l_ulong __spare[4];
};
/* Scheduling policies */
#define LINUX_SCHED_OTHER 0
#define LINUX_SCHED_FIFO 1
#define LINUX_SCHED_RR 2
/* Resource limits */
#define LINUX_RLIMIT_CPU 0
#define LINUX_RLIMIT_FSIZE 1
@ -456,20 +448,6 @@ struct l_pollfd {
l_short revents;
};
#define LINUX_CLONE_VM 0x00000100
#define LINUX_CLONE_FS 0x00000200
#define LINUX_CLONE_FILES 0x00000400
#define LINUX_CLONE_SIGHAND 0x00000800
#define LINUX_CLONE_PID 0x00001000 /* No longer exist in Linux */
#define LINUX_CLONE_VFORK 0x00004000
#define LINUX_CLONE_PARENT 0x00008000
#define LINUX_CLONE_THREAD 0x00010000
#define LINUX_CLONE_SETTLS 0x00080000
#define LINUX_CLONE_PARENT_SETTID 0x00100000
#define LINUX_CLONE_CHILD_CLEARTID 0x00200000
#define LINUX_CLONE_CHILD_SETTID 0x01000000
#define LINUX_ARCH_SET_GS 0x1001
#define LINUX_ARCH_SET_FS 0x1002
#define LINUX_ARCH_GET_FS 0x1003

View File

@ -76,6 +76,14 @@ device iic
device iicbus
device twsi
# Wireless NIC cards
device wlan # 802.11 support
device ath # Atheros NIC's
device ath_pci # Atheros pci/cardbus glue
device ath_hal
device ath_rate_sample
options ATH_ENABLE_11N
# CESA
device cesa
device crypto

View File

@ -97,6 +97,14 @@ struct devsw netdev = {
net_cleanup
};
static struct uri_scheme {
const char *scheme;
int proto;
} uri_schemes[] = {
{ "tftp:/", NET_TFTP },
{ "nfs:/", NET_NFS },
};
static int
net_init(void)
{
@ -248,8 +256,6 @@ net_getparams(int sock)
{
char buf[MAXHOSTNAMELEN];
n_long rootaddr, smask;
struct iodesc *d = socktodesc(sock);
extern struct in_addr servip;
#ifdef SUPPORT_BOOTP
/*
@ -258,26 +264,8 @@ net_getparams(int sock)
* be initialized. If any remain uninitialized, we will
* use RARP and RPC/bootparam (the Sun way) to get them.
*/
if (try_bootp) {
int rc = -1;
if (bootp_response != NULL) {
rc = dhcp_try_rfc1048(bootp_response->bp_vend,
bootp_response_size -
offsetof(struct bootp, bp_vend));
if (servip.s_addr == 0)
servip = bootp_response->bp_siaddr;
if (rootip.s_addr == 0)
rootip = bootp_response->bp_siaddr;
if (gateip.s_addr == 0)
gateip = bootp_response->bp_giaddr;
if (myip.s_addr == 0)
myip = bootp_response->bp_yiaddr;
d->myip = myip;
}
if (rc < 0)
bootp(sock, BOOTP_NONE);
}
if (try_bootp)
bootp(sock);
if (myip.s_addr != 0)
goto exit;
#ifdef NETIF_DEBUG
@ -334,11 +322,8 @@ net_getparams(int sock)
return (EIO);
}
exit:
netproto = NET_TFTP;
if ((rootaddr = net_parse_rootpath()) != INADDR_NONE) {
netproto = NET_NFS;
if ((rootaddr = net_parse_rootpath()) != INADDR_NONE)
rootip.s_addr = rootaddr;
}
#ifdef NETIF_DEBUG
if (debug) {
@ -381,20 +366,69 @@ net_print(int verbose)
}
/*
* Strip the server's address off of the rootpath if present and return it in
* network byte order, leaving just the pathname part in the global rootpath.
* Parses the rootpath if present
*
* The rootpath format can be in the form
* <scheme>://ip/path
* <scheme>:/path
*
* For compatibility with previous behaviour it also accepts as an NFS scheme
* ip:/path
* /path
*
* If an ip is set it returns it in network byte order.
* The default scheme defined in the global netproto, if not set it defaults to
* NFS.
* It leaves just the pathname in the global rootpath.
*/
uint32_t
net_parse_rootpath()
{
n_long addr = INADDR_NONE;
char *ptr;
n_long addr = htonl(INADDR_NONE);
size_t i;
char ip[FNAME_SIZE];
char *ptr, *val;
netproto = NET_NONE;
for (i = 0; i < nitems(uri_schemes); i++) {
if (strncmp(rootpath, uri_schemes[i].scheme,
strlen(uri_schemes[i].scheme)) != 0)
continue;
netproto = uri_schemes[i].proto;
break;
}
ptr = rootpath;
(void)strsep(&ptr, ":");
if (ptr != NULL) {
addr = inet_addr(rootpath);
bcopy(ptr, rootpath, strlen(ptr) + 1);
/* Fallback for compatibility mode */
if (netproto == NET_NONE) {
netproto = NET_NFS;
(void)strsep(&ptr, ":");
if (ptr != NULL) {
addr = inet_addr(rootpath);
bcopy(ptr, rootpath, strlen(ptr) + 1);
}
} else {
ptr += strlen(uri_schemes[i].scheme);
if (*ptr == '/') {
/* we are in the form <scheme>://, we do expect an ip */
ptr++;
/*
* XXX when http will be there we will need to check for
* a port, but right now we do not need it yet
*/
val = strchr(ptr, '/');
if (val != NULL) {
snprintf(ip, sizeof(ip), "%.*s",
(int)((uintptr_t)val - (uintptr_t)ptr),
ptr);
addr = inet_addr(ip);
bcopy(val, rootpath, strlen(val) + 1);
}
} else {
ptr--;
bcopy(ptr, rootpath, strlen(ptr) + 1);
}
}
return (addr);

View File

@ -10,6 +10,8 @@ INTERNALPROG=
NEWVERSWHAT?= "bootstrap loader" x86
VERSION_FILE= ${.CURDIR}/../loader/version
LOADER_NET_SUPPORT?= yes
LOADER_NFS_SUPPORT?= yes
LOADER_TFTP_SUPPORT?= yes
# architecture-specific loader code
SRCS= main.c conf.c vers.c
@ -30,10 +32,10 @@ LIBZFSBOOT= ${.OBJDIR}/../../zfs/libzfsboot.a
CFLAGS+= -I${.CURDIR}/../../../../lib/libstand
.endif
# Enable PXE TFTP or NFS support, not both.
.if defined(LOADER_TFTP_SUPPORT)
CFLAGS+= -DLOADER_TFTP_SUPPORT
.else
.endif
.if defined(LOADER_NFS_SUPPORT)
CFLAGS+= -DLOADER_NFS_SUPPORT
.endif

View File

@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd May 16, 2017
.Dd May 27, 2017
.Dt PXEBOOT 8
.Os
.Sh NAME
@ -39,6 +39,11 @@ configured to run under Intel's Preboot Execution Environment (PXE) system.
PXE is a form of smart boot ROM, built into Intel EtherExpress Pro/100 and
3Com 3c905c Ethernet cards, and Ethernet-equipped Intel motherboards.
PXE supports DHCP configuration and provides low-level NIC access services.
.Pp
The DHCP client will set a DHCP user class named
.Va FreeBSD
to allow flexible configuration of the DHCP server.
.Pp
The
.Nm
bootloader retrieves the kernel, modules,
@ -69,6 +74,9 @@ max-lease-time 120;
subnet 10.0.0.0 netmask 255.255.255.0 {
filename "pxeboot";
range 10.0.0.10 10.0.0.254;
if exists user-class and option user-class = "FreeBSD" {
option root-path "tftp://10.0.0.1/FreeBSD";
}
}
.Ed
@ -85,6 +93,27 @@ expects to fetch
.Pa /boot/loader.rc
from the specified server before loading any other files.
.Pp
Valid
.Va option root-path
Syntax is the following
.Bl -tag -width <scheme>://ip/path indent
.It /path
path to the root filesystem on the NFS server
.It ip:/path
path to the root filesystem on the NFS server
.Ar ip
.It nfs:/path
path to the root filesystem on the NFS server
.It nfs://ip/path
path to the root filesystem on the NFS server
.Ar ip
.It tftp:/path
path to the root filesystem on the TFTP server
.It tftp://ip/path
path to the root filesystem on the TFTP server
.Ar ip
.El
.Pp
.Nm
defaults to a conservative 1024 byte NFS data packet size.
This may be changed by setting the

View File

@ -682,6 +682,13 @@ static struct da_quirk_entry da_quirk_table[] =
{T_DIRECT, SIP_MEDIA_REMOVABLE, "*" , "USB DISK*",
"*"}, /*quirks*/ DA_Q_NO_SYNC_CACHE
},
{
/*
* Genesys GL3224
*/
{T_DIRECT, SIP_MEDIA_REMOVABLE, "Generic*", "STORAGE DEVICE*",
"120?"}, /*quirks*/ DA_Q_NO_SYNC_CACHE | DA_Q_4K | DA_Q_NO_RC16
},
{
/*
* Genesys 6-in-1 Card Reader

View File

@ -546,6 +546,14 @@ static struct scsi_quirk_entry scsi_quirk_table[] =
{ T_DIRECT, SIP_MEDIA_REMOVABLE, "Garmin", "*", "*" },
CAM_QUIRK_NORPTLUNS, /*mintags*/2, /*maxtags*/255
},
{
{ T_DIRECT, SIP_MEDIA_REMOVABLE, "Generic", "STORAGE DEVICE*", "120?" },
CAM_QUIRK_NORPTLUNS, /*mintags*/2, /*maxtags*/255
},
{
{ T_DIRECT, SIP_MEDIA_REMOVABLE, "Generic", "MassStorageClass", "1533" },
CAM_QUIRK_NORPTLUNS, /*mintags*/2, /*maxtags*/255
},
{
/* Default tagged queuing parameters for all devices */
{

View File

@ -497,7 +497,7 @@ zfsctl_common_getattr(vnode_t *vp, vattr_t *vap)
vap->va_blksize = 0;
vap->va_nblocks = 0;
vap->va_seq = 0;
vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
vn_fsid(vp, vap);
vap->va_mode = S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP |
S_IROTH | S_IXOTH;
vap->va_type = VDIR;

View File

@ -1635,7 +1635,7 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct componentname *cnp,
cn.cn_nameptr = "snapshot";
cn.cn_namelen = strlen(cn.cn_nameptr);
cn.cn_nameiop = cnp->cn_nameiop;
cn.cn_flags = cnp->cn_flags;
cn.cn_flags = cnp->cn_flags & ~ISDOTDOT;
cn.cn_lkflags = cnp->cn_lkflags;
error = VOP_LOOKUP(zfsctl_vp, vpp, &cn);
vput(zfsctl_vp);
@ -2708,7 +2708,7 @@ zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
#ifdef illumos
vap->va_fsid = zp->z_zfsvfs->z_vfs->vfs_dev;
#else
vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
vn_fsid(vp, vap);
#endif
vap->va_nodeid = zp->z_id;
if ((vp->v_flag & VROOT) && zfs_show_ctldir(zp))

View File

@ -31,6 +31,9 @@
__FBSDID("$FreeBSD$");
#include "opt_compat.h"
#if defined(KLD_MODULE)
#include "opt_global.h"
#endif
#include <sys/param.h>
#include <sys/blist.h>
@ -2516,6 +2519,7 @@ linux_getrandom(struct thread *td, struct linux_getrandom_args *args)
{
struct uio uio;
struct iovec iov;
int error;
if (args->flags & ~(LINUX_GRND_NONBLOCK|LINUX_GRND_RANDOM))
return (EINVAL);
@ -2532,7 +2536,10 @@ linux_getrandom(struct thread *td, struct linux_getrandom_args *args)
uio.uio_rw = UIO_READ;
uio.uio_td = td;
return (read_random_uio(&uio, args->flags & LINUX_GRND_NONBLOCK));
error = read_random_uio(&uio, args->flags & LINUX_GRND_NONBLOCK);
if (error == 0)
td->td_retval[0] = args->count - uio.uio_resid;
return (error);
}
int

View File

@ -8,6 +8,8 @@
# the code here when they all produce identical results
# (or should)
.if !defined(KERNBUILDDIR)
opt_global.h:
echo "#define DEV_RANDOM 1" >> ${.TARGET}
opt_bpf.h:
echo "#define DEV_BPF 1" > ${.TARGET}
.if ${MK_INET_SUPPORT} != "no"

View File

@ -3525,6 +3525,7 @@ geom/virstor/binstream.c optional geom_virstor
geom/virstor/g_virstor.c optional geom_virstor
geom/virstor/g_virstor_md.c optional geom_virstor
geom/zero/g_zero.c optional geom_zero
fs/ext2fs/ext2_acl.c optional ext2fs
fs/ext2fs/ext2_alloc.c optional ext2fs
fs/ext2fs/ext2_balloc.c optional ext2fs
fs/ext2fs/ext2_bmap.c optional ext2fs

View File

@ -497,9 +497,7 @@ ipf_nat_soft_init(softc, arg)
softn->ipf_nat_pending.ifq_next = NULL;
for (i = 0, tq = softn->ipf_nat_tcptq; i < IPF_TCP_NSTATES; i++, tq++) {
#ifdef LARGE_NAT
if (tq->ifq_ttl < softn->ipf_nat_deficmpage)
#endif
tq->ifq_ttl = softn->ipf_nat_deficmpage;
#ifdef LARGE_NAT
else if (tq->ifq_ttl > softn->ipf_nat_defage)

View File

@ -939,7 +939,7 @@ ipf_sync_nat(softc, sp, data)
nat_t *n, *nat;
synclist_t *sl;
u_int hv = 0;
int err;
int err = 0;
READ_ENTER(&softs->ipf_syncnat);
@ -1016,7 +1016,7 @@ ipf_sync_nat(softc, sp, data)
}
RWLOCK_EXIT(&softs->ipf_syncnat);
return 0;
return err;
}

View File

@ -302,7 +302,7 @@ ath_hal_rf_name(struct ath_hal *ah)
HAL_BOOL
ath_hal_wait(struct ath_hal *ah, u_int reg, uint32_t mask, uint32_t val)
{
#define AH_TIMEOUT 1000
#define AH_TIMEOUT 5000
return ath_hal_waitfor(ah, reg, mask, val, AH_TIMEOUT);
#undef AH_TIMEOUT
}

View File

@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$");
#include "opt_isa.h"
#include "opt_psm.h"
#include "opt_evdev.h"
#include <sys/param.h>
#include <sys/systm.h>
@ -90,6 +91,11 @@ __FBSDID("$FreeBSD$");
#include <isa/isavar.h>
#endif
#ifdef EVDEV_SUPPORT
#include <dev/evdev/evdev.h>
#include <dev/evdev/input.h>
#endif
#include <dev/atkbdc/atkbdcreg.h>
#include <dev/atkbdc/psm.h>
@ -325,8 +331,14 @@ typedef struct elantechhw {
#define ELANTECH_REG_RDWR 0x00
#define ELANTECH_CUSTOM_CMD 0xf8
#ifdef EVDEV_SUPPORT
#define ELANTECH_MAX_FINGERS 5
#else
#define ELANTECH_MAX_FINGERS PSM_FINGERS
#endif
#define ELANTECH_FINGER_MAX_P 255
#define ELANTECH_FINGER_MAX_W 15
#define ELANTECH_FINGER_SET_XYP(pb) (finger_t) { \
.x = (((pb)->ipacket[1] & 0x0f) << 8) | (pb)->ipacket[2], \
.y = (((pb)->ipacket[4] & 0x0f) << 8) | (pb)->ipacket[5], \
@ -418,6 +430,10 @@ struct psm_softc { /* Driver status information */
int cmdcount;
struct sigio *async; /* Processes waiting for SIGIO */
int extended_buttons;
#ifdef EVDEV_SUPPORT
struct evdev_dev *evdev_a; /* Absolute reporting device */
struct evdev_dev *evdev_r; /* Relative reporting device */
#endif
};
static devclass_t psm_devclass;
@ -427,6 +443,8 @@ static devclass_t psm_devclass;
#define PSM_ASLP 2 /* Waiting for mouse data */
#define PSM_SOFTARMED 4 /* Software interrupt armed */
#define PSM_NEED_SYNCBITS 8 /* Set syncbits using next data pkt */
#define PSM_EV_OPEN_R 0x10 /* Relative evdev device is open */
#define PSM_EV_OPEN_A 0x20 /* Absolute evdev device is open */
/* driver configuration flags (config) */
#define PSM_CONFIG_RESOLUTION 0x000f /* resolution */
@ -532,13 +550,23 @@ static int psmattach(device_t);
static int psmdetach(device_t);
static int psmresume(device_t);
static d_open_t psmopen;
static d_close_t psmclose;
static d_open_t psm_cdev_open;
static d_close_t psm_cdev_close;
static d_read_t psmread;
static d_write_t psmwrite;
static d_ioctl_t psmioctl;
static d_poll_t psmpoll;
static int psmopen(struct psm_softc *);
static int psmclose(struct psm_softc *);
#ifdef EVDEV_SUPPORT
static evdev_open_t psm_ev_open_r;
static evdev_close_t psm_ev_close_r;
static evdev_open_t psm_ev_open_a;
static evdev_close_t psm_ev_close_a;
#endif
static int enable_aux_dev(KBDC);
static int disable_aux_dev(KBDC);
static int get_mouse_status(KBDC, int *, int, int);
@ -668,8 +696,8 @@ static driver_t psm_driver = {
static struct cdevsw psm_cdevsw = {
.d_version = D_VERSION,
.d_flags = D_NEEDGIANT,
.d_open = psmopen,
.d_close = psmclose,
.d_open = psm_cdev_open,
.d_close = psm_cdev_close,
.d_read = psmread,
.d_write = psmwrite,
.d_ioctl = psmioctl,
@ -677,6 +705,17 @@ static struct cdevsw psm_cdevsw = {
.d_name = PSM_DRIVER_NAME,
};
#ifdef EVDEV_SUPPORT
static const struct evdev_methods psm_ev_methods_r = {
.ev_open = psm_ev_open_r,
.ev_close = psm_ev_close_r,
};
static const struct evdev_methods psm_ev_methods_a = {
.ev_open = psm_ev_open_a,
.ev_close = psm_ev_close_a,
};
#endif
/* device I/O routines */
static int
enable_aux_dev(KBDC kbdc)
@ -1197,7 +1236,8 @@ reinitialize(struct psm_softc *sc, int doinit)
splx(s);
/* restore the driver state */
if ((sc->state & PSM_OPEN) && (err == 0)) {
if ((sc->state & (PSM_OPEN | PSM_EV_OPEN_R | PSM_EV_OPEN_A)) &&
(err == 0)) {
/* enable the aux device and the port again */
err = doopen(sc, c);
if (err != 0)
@ -1578,6 +1618,270 @@ psmprobe(device_t dev)
return (0);
}
#ifdef EVDEV_SUPPORT
/* Values are taken from Linux drivers for userland software compatibility */
#define PS2_MOUSE_VENDOR 0x0002
#define PS2_MOUSE_GENERIC_PRODUCT 0x0001
#define PS2_MOUSE_SYNAPTICS_NAME "SynPS/2 Synaptics TouchPad"
#define PS2_MOUSE_SYNAPTICS_PRODUCT 0x0007
#define PS2_MOUSE_TRACKPOINT_NAME "TPPS/2 IBM TrackPoint"
#define PS2_MOUSE_TRACKPOINT_PRODUCT 0x000A
#define PS2_MOUSE_ELANTECH_NAME "ETPS/2 Elantech Touchpad"
#define PS2_MOUSE_ELANTECH_ST_NAME "ETPS/2 Elantech TrackPoint"
#define PS2_MOUSE_ELANTECH_PRODUCT 0x000E
#define ABSINFO_END { ABS_CNT, 0, 0, 0 }
static void
psm_support_abs_bulk(struct evdev_dev *evdev, const uint16_t info[][4])
{
size_t i;
for (i = 0; info[i][0] != ABS_CNT; i++)
evdev_support_abs(evdev, info[i][0], 0, info[i][1], info[i][2],
0, 0, info[i][3]);
}
static void
psm_push_mt_finger(struct psm_softc *sc, int id, const finger_t *f)
{
int y = sc->synhw.minimumYCoord + sc->synhw.maximumYCoord - f->y;
evdev_push_abs(sc->evdev_a, ABS_MT_SLOT, id);
evdev_push_abs(sc->evdev_a, ABS_MT_TRACKING_ID, id);
evdev_push_abs(sc->evdev_a, ABS_MT_POSITION_X, f->x);
evdev_push_abs(sc->evdev_a, ABS_MT_POSITION_Y, y);
evdev_push_abs(sc->evdev_a, ABS_MT_PRESSURE, f->p);
}
static void
psm_push_st_finger(struct psm_softc *sc, const finger_t *f)
{
int y = sc->synhw.minimumYCoord + sc->synhw.maximumYCoord - f->y;
evdev_push_abs(sc->evdev_a, ABS_X, f->x);
evdev_push_abs(sc->evdev_a, ABS_Y, y);
evdev_push_abs(sc->evdev_a, ABS_PRESSURE, f->p);
if (sc->synhw.capPalmDetect)
evdev_push_abs(sc->evdev_a, ABS_TOOL_WIDTH, f->w);
}
static void
psm_release_mt_slot(struct evdev_dev *evdev, int32_t slot)
{
evdev_push_abs(evdev, ABS_MT_SLOT, slot);
evdev_push_abs(evdev, ABS_MT_TRACKING_ID, -1);
}
static int
psm_register(device_t dev, int model_code)
{
struct psm_softc *sc = device_get_softc(dev);
struct evdev_dev *evdev_r;
int error, i, nbuttons, nwheels, product;
bool is_pointing_stick;
const char *name;
name = model_name(model_code);
nbuttons = sc->hw.buttons;
product = PS2_MOUSE_GENERIC_PRODUCT;
nwheels = 0;
is_pointing_stick = false;
switch (model_code) {
case MOUSE_MODEL_TRACKPOINT:
name = PS2_MOUSE_TRACKPOINT_NAME;
product = PS2_MOUSE_TRACKPOINT_PRODUCT;
nbuttons = 3;
is_pointing_stick = true;
break;
case MOUSE_MODEL_ELANTECH:
name = PS2_MOUSE_ELANTECH_ST_NAME;
product = PS2_MOUSE_ELANTECH_PRODUCT;
nbuttons = 3;
is_pointing_stick = true;
break;
case MOUSE_MODEL_MOUSEMANPLUS:
case MOUSE_MODEL_4D:
nwheels = 2;
break;
case MOUSE_MODEL_EXPLORER:
case MOUSE_MODEL_INTELLI:
case MOUSE_MODEL_NET:
case MOUSE_MODEL_NETSCROLL:
case MOUSE_MODEL_4DPLUS:
nwheels = 1;
break;
}
evdev_r = evdev_alloc();
evdev_set_name(evdev_r, name);
evdev_set_phys(evdev_r, device_get_nameunit(dev));
evdev_set_id(evdev_r, BUS_I8042, PS2_MOUSE_VENDOR, product, 0);
evdev_set_methods(evdev_r, sc, &psm_ev_methods_r);
evdev_support_prop(evdev_r, INPUT_PROP_POINTER);
if (is_pointing_stick)
evdev_support_prop(evdev_r, INPUT_PROP_POINTING_STICK);
evdev_support_event(evdev_r, EV_SYN);
evdev_support_event(evdev_r, EV_KEY);
evdev_support_event(evdev_r, EV_REL);
evdev_support_rel(evdev_r, REL_X);
evdev_support_rel(evdev_r, REL_Y);
switch (nwheels) {
case 2:
evdev_support_rel(evdev_r, REL_HWHEEL);
/* FALLTHROUGH */
case 1:
evdev_support_rel(evdev_r, REL_WHEEL);
}
for (i = 0; i < nbuttons; i++)
evdev_support_key(evdev_r, BTN_MOUSE + i);
error = evdev_register_mtx(evdev_r, &Giant);
if (error)
evdev_free(evdev_r);
else
sc->evdev_r = evdev_r;
return (error);
}
static int
psm_register_synaptics(device_t dev)
{
struct psm_softc *sc = device_get_softc(dev);
const uint16_t synaptics_absinfo_st[][4] = {
{ ABS_X, sc->synhw.minimumXCoord,
sc->synhw.maximumXCoord, sc->synhw.infoXupmm },
{ ABS_Y, sc->synhw.minimumYCoord,
sc->synhw.maximumYCoord, sc->synhw.infoYupmm },
{ ABS_PRESSURE, 0, ELANTECH_FINGER_MAX_P, 0 },
ABSINFO_END,
};
const uint16_t synaptics_absinfo_mt[][4] = {
{ ABS_MT_SLOT, 0, PSM_FINGERS-1, 0},
{ ABS_MT_TRACKING_ID, -1, PSM_FINGERS-1, 0},
{ ABS_MT_POSITION_X, sc->synhw.minimumXCoord,
sc->synhw.maximumXCoord, sc->synhw.infoXupmm },
{ ABS_MT_POSITION_Y, sc->synhw.minimumYCoord,
sc->synhw.maximumYCoord, sc->synhw.infoYupmm },
{ ABS_MT_PRESSURE, 0, ELANTECH_FINGER_MAX_P, 0 },
ABSINFO_END,
};
struct evdev_dev *evdev_a;
int error, i, guest_model;
evdev_a = evdev_alloc();
evdev_set_name(evdev_a, PS2_MOUSE_SYNAPTICS_NAME);
evdev_set_phys(evdev_a, device_get_nameunit(dev));
evdev_set_id(evdev_a, BUS_I8042, PS2_MOUSE_VENDOR,
PS2_MOUSE_SYNAPTICS_PRODUCT, 0);
evdev_set_methods(evdev_a, sc, &psm_ev_methods_a);
evdev_support_event(evdev_a, EV_SYN);
evdev_support_event(evdev_a, EV_KEY);
evdev_support_event(evdev_a, EV_ABS);
evdev_support_prop(evdev_a, INPUT_PROP_POINTER);
if (sc->synhw.capAdvancedGestures)
evdev_support_prop(evdev_a, INPUT_PROP_SEMI_MT);
if (sc->synhw.capClickPad)
evdev_support_prop(evdev_a, INPUT_PROP_BUTTONPAD);
evdev_support_key(evdev_a, BTN_TOUCH);
evdev_support_nfingers(evdev_a, 3);
psm_support_abs_bulk(evdev_a, synaptics_absinfo_st);
if (sc->synhw.capAdvancedGestures || sc->synhw.capReportsV)
psm_support_abs_bulk(evdev_a, synaptics_absinfo_mt);
if (sc->synhw.capPalmDetect)
evdev_support_abs(evdev_a, ABS_TOOL_WIDTH, 0, 0, 15, 0, 0, 0);
evdev_support_key(evdev_a, BTN_LEFT);
if (!sc->synhw.capClickPad) {
evdev_support_key(evdev_a, BTN_RIGHT);
if (sc->synhw.capExtended && sc->synhw.capMiddle)
evdev_support_key(evdev_a, BTN_MIDDLE);
}
if (sc->synhw.capExtended && sc->synhw.capFourButtons) {
evdev_support_key(evdev_a, BTN_BACK);
evdev_support_key(evdev_a, BTN_FORWARD);
}
if (sc->synhw.capExtended && (sc->synhw.nExtendedButtons > 0))
for (i = 0; i < sc->synhw.nExtendedButtons; i++)
evdev_support_key(evdev_a, BTN_0 + i);
error = evdev_register_mtx(evdev_a, &Giant);
if (!error && sc->synhw.capPassthrough) {
guest_model = sc->tpinfo.sysctl_tree != NULL ?
MOUSE_MODEL_TRACKPOINT : MOUSE_MODEL_GENERIC;
error = psm_register(dev, guest_model);
}
if (error)
evdev_free(evdev_a);
else
sc->evdev_a = evdev_a;
return (error);
}
static int
psm_register_elantech(device_t dev)
{
struct psm_softc *sc = device_get_softc(dev);
const uint16_t elantech_absinfo[][4] = {
{ ABS_X, 0, sc->elanhw.sizex,
sc->elanhw.dpmmx },
{ ABS_Y, 0, sc->elanhw.sizey,
sc->elanhw.dpmmy },
{ ABS_PRESSURE, 0, ELANTECH_FINGER_MAX_P, 0 },
{ ABS_TOOL_WIDTH, 0, ELANTECH_FINGER_MAX_W, 0 },
{ ABS_MT_SLOT, 0, ELANTECH_MAX_FINGERS - 1, 0 },
{ ABS_MT_TRACKING_ID, -1, ELANTECH_MAX_FINGERS - 1, 0 },
{ ABS_MT_POSITION_X, 0, sc->elanhw.sizex,
sc->elanhw.dpmmx },
{ ABS_MT_POSITION_Y, 0, sc->elanhw.sizey,
sc->elanhw.dpmmy },
{ ABS_MT_PRESSURE, 0, ELANTECH_FINGER_MAX_P, 0 },
{ ABS_MT_TOUCH_MAJOR, 0, ELANTECH_FINGER_MAX_W *
sc->elanhw.dptracex, 0 },
ABSINFO_END,
};
struct evdev_dev *evdev_a;
int error;
evdev_a = evdev_alloc();
evdev_set_name(evdev_a, PS2_MOUSE_ELANTECH_NAME);
evdev_set_phys(evdev_a, device_get_nameunit(dev));
evdev_set_id(evdev_a, BUS_I8042, PS2_MOUSE_VENDOR,
PS2_MOUSE_ELANTECH_PRODUCT, 0);
evdev_set_methods(evdev_a, sc, &psm_ev_methods_a);
evdev_support_event(evdev_a, EV_SYN);
evdev_support_event(evdev_a, EV_KEY);
evdev_support_event(evdev_a, EV_ABS);
evdev_support_prop(evdev_a, INPUT_PROP_POINTER);
if (sc->elanhw.issemimt)
evdev_support_prop(evdev_a, INPUT_PROP_SEMI_MT);
if (sc->elanhw.isclickpad)
evdev_support_prop(evdev_a, INPUT_PROP_BUTTONPAD);
evdev_support_key(evdev_a, BTN_TOUCH);
evdev_support_nfingers(evdev_a, ELANTECH_MAX_FINGERS);
evdev_support_key(evdev_a, BTN_LEFT);
if (!sc->elanhw.isclickpad)
evdev_support_key(evdev_a, BTN_RIGHT);
psm_support_abs_bulk(evdev_a, elantech_absinfo);
error = evdev_register_mtx(evdev_a, &Giant);
if (!error && sc->elanhw.hastrackpoint)
error = psm_register(dev, MOUSE_MODEL_ELANTECH);
if (error)
evdev_free(evdev_a);
else
sc->evdev_a = evdev_a;
return (error);
}
#endif
static int
psmattach(device_t dev)
{
@ -1609,6 +1913,24 @@ psmattach(device_t dev)
sc->bdev = make_dev(&psm_cdevsw, 0, 0, 0, 0666, "bpsm%d", unit);
sc->bdev->si_drv1 = sc;
#ifdef EVDEV_SUPPORT
switch (sc->hw.model) {
case MOUSE_MODEL_SYNAPTICS:
error = psm_register_synaptics(dev);
break;
case MOUSE_MODEL_ELANTECH:
error = psm_register_elantech(dev);
break;
default:
error = psm_register(dev, sc->hw.model);
}
if (error)
return (error);
#endif
/* Some touchpad devices need full reinitialization after suspend. */
switch (sc->hw.model) {
case MOUSE_MODEL_SYNAPTICS:
@ -1657,6 +1979,11 @@ psmdetach(device_t dev)
if (sc->state & PSM_OPEN)
return (EBUSY);
#ifdef EVDEV_SUPPORT
evdev_free(sc->evdev_r);
evdev_free(sc->evdev_a);
#endif
rid = KBDC_RID_AUX;
bus_teardown_intr(dev, sc->intr, sc->ih);
bus_release_resource(dev, SYS_RES_IRQ, rid, sc->intr);
@ -1670,13 +1997,83 @@ psmdetach(device_t dev)
return (0);
}
#ifdef EVDEV_SUPPORT
static int
psmopen(struct cdev *dev, int flag, int fmt, struct thread *td)
psm_ev_open_r(struct evdev_dev *evdev, void *ev_softc)
{
struct psm_softc *sc = (struct psm_softc *)ev_softc;
int err = 0;
/* Get device data */
if ((sc->state & PSM_VALID) == 0) {
/* the device is no longer valid/functioning */
return (ENXIO);
}
if (!(sc->state & (PSM_OPEN | PSM_EV_OPEN_A)))
err = psmopen(sc);
if (err == 0)
sc->state |= PSM_EV_OPEN_R;
return (err);
}
static void
psm_ev_close_r(struct evdev_dev *evdev, void *ev_softc)
{
struct psm_softc *sc = (struct psm_softc *)ev_softc;
sc->state &= ~PSM_EV_OPEN_R;
if (sc->state & (PSM_OPEN | PSM_EV_OPEN_A))
return;
if (sc->state & PSM_VALID)
psmclose(sc);
}
static int
psm_ev_open_a(struct evdev_dev *evdev, void *ev_softc)
{
struct psm_softc *sc = (struct psm_softc *)ev_softc;
int err = 0;
/* Get device data */
if ((sc->state & PSM_VALID) == 0) {
/* the device is no longer valid/functioning */
return (ENXIO);
}
if (!(sc->state & (PSM_OPEN | PSM_EV_OPEN_R)))
err = psmopen(sc);
if (err == 0)
sc->state |= PSM_EV_OPEN_A;
return (err);
}
static void
psm_ev_close_a(struct evdev_dev *evdev, void *ev_softc)
{
struct psm_softc *sc = (struct psm_softc *)ev_softc;
sc->state &= ~PSM_EV_OPEN_A;
if (sc->state & (PSM_OPEN | PSM_EV_OPEN_R))
return;
if (sc->state & PSM_VALID)
psmclose(sc);
}
#endif
static int
psm_cdev_open(struct cdev *dev, int flag, int fmt, struct thread *td)
{
struct psm_softc *sc;
int command_byte;
int err;
int s;
int err = 0;
/* Get device data */
sc = dev->si_drv1;
@ -1691,6 +2088,59 @@ psmopen(struct cdev *dev, int flag, int fmt, struct thread *td)
device_busy(devclass_get_device(psm_devclass, sc->unit));
#ifdef EVDEV_SUPPORT
/* Already opened by evdev */
if (!(sc->state & (PSM_EV_OPEN_R | PSM_EV_OPEN_A)))
#endif
err = psmopen(sc);
if (err == 0)
sc->state |= PSM_OPEN;
else
device_unbusy(devclass_get_device(psm_devclass, sc->unit));
return (err);
}
static int
psm_cdev_close(struct cdev *dev, int flag, int fmt, struct thread *td)
{
struct psm_softc *sc;
int err = 0;
/* Get device data */
sc = dev->si_drv1;
if ((sc == NULL) || (sc->state & PSM_VALID) == 0) {
/* the device is no longer valid/functioning */
return (ENXIO);
}
#ifdef EVDEV_SUPPORT
/* Still opened by evdev */
if (!(sc->state & (PSM_EV_OPEN_R | PSM_EV_OPEN_A)))
#endif
err = psmclose(sc);
if (err == 0) {
sc->state &= ~PSM_OPEN;
/* clean up and sigio requests */
if (sc->async != NULL) {
funsetown(&sc->async);
sc->async = NULL;
}
device_unbusy(devclass_get_device(psm_devclass, sc->unit));
}
return (err);
}
static int
psmopen(struct psm_softc *sc)
{
int command_byte;
int err;
int s;
/* Initialize state */
sc->mode.level = sc->dflt_mode.level;
sc->mode.protocol = sc->dflt_mode.protocol;
@ -1750,16 +2200,13 @@ psmopen(struct cdev *dev, int flag, int fmt, struct thread *td)
err = doopen(sc, command_byte);
/* done */
if (err == 0)
sc->state |= PSM_OPEN;
kbdc_lock(sc->kbdc, FALSE);
return (err);
}
static int
psmclose(struct cdev *dev, int flag, int fmt, struct thread *td)
psmclose(struct psm_softc *sc)
{
struct psm_softc *sc = dev->si_drv1;
int stat[3];
int command_byte;
int s;
@ -1836,16 +2283,8 @@ psmclose(struct cdev *dev, int flag, int fmt, struct thread *td)
/* remove anything left in the output buffer */
empty_aux_buffer(sc->kbdc, 10);
/* clean up and sigio requests */
if (sc->async != NULL) {
funsetown(&sc->async);
sc->async = NULL;
}
/* close is almost always successful */
sc->state &= ~PSM_OPEN;
kbdc_lock(sc->kbdc, FALSE);
device_unbusy(devclass_get_device(psm_devclass, sc->unit));
return (0);
}
@ -2496,7 +2935,7 @@ psmintr(void *arg)
pb = &sc->pqueue[sc->pqueue_end];
/* discard the byte if the device is not open */
if ((sc->state & PSM_OPEN) == 0)
if (!(sc->state & (PSM_OPEN | PSM_EV_OPEN_R | PSM_EV_OPEN_A)))
continue;
getmicrouptime(&now);
@ -2854,7 +3293,15 @@ proc_synaptics(struct psm_softc *sc, packetbuf_t *pb, mousestatus_t *ms,
guest_buttons |= MOUSE_BUTTON2DOWN;
if (pb->ipacket[1] & 0x02)
guest_buttons |= MOUSE_BUTTON3DOWN;
#ifdef EVDEV_SUPPORT
if (evdev_rcpt_mask & EVDEV_RCPT_HW_MOUSE) {
evdev_push_rel(sc->evdev_r, REL_X, *x);
evdev_push_rel(sc->evdev_r, REL_Y, -*y);
evdev_push_mouse_btn(sc->evdev_r,
guest_buttons);
evdev_sync(sc->evdev_r);
}
#endif
ms->button = touchpad_buttons | guest_buttons |
sc->extended_buttons;
}
@ -2965,6 +3412,24 @@ proc_synaptics(struct psm_softc *sc, packetbuf_t *pb, mousestatus_t *ms,
int mask = 0;
maskedbits = (sc->synhw.nExtendedButtons + 1) >> 1;
mask = (1 << maskedbits) - 1;
#ifdef EVDEV_SUPPORT
int i;
if (evdev_rcpt_mask & EVDEV_RCPT_HW_MOUSE) {
if (sc->synhw.capPassthrough) {
evdev_push_mouse_btn(sc->evdev_r,
extended_buttons);
evdev_sync(sc->evdev_r);
}
for (i = 0; i < maskedbits; i++) {
evdev_push_key(sc->evdev_a,
BTN_0 + i * 2,
pb->ipacket[4] & (1 << i));
evdev_push_key(sc->evdev_a,
BTN_0 + i * 2 + 1,
pb->ipacket[5] & (1 << i));
}
}
#endif
pb->ipacket[4] &= ~(mask);
pb->ipacket[5] &= ~(mask);
} else if (!sc->syninfo.directional_scrolls &&
@ -3016,6 +3481,31 @@ proc_synaptics(struct psm_softc *sc, packetbuf_t *pb, mousestatus_t *ms,
if (id >= nfingers)
PSM_FINGER_RESET(f[id]);
#ifdef EVDEV_SUPPORT
if (evdev_rcpt_mask & EVDEV_RCPT_HW_MOUSE) {
for (id = 0; id < PSM_FINGERS; id++) {
if (PSM_FINGER_IS_SET(f[id]))
psm_push_mt_finger(sc, id, &f[id]);
else
psm_release_mt_slot(sc->evdev_a, id);
}
evdev_push_key(sc->evdev_a, BTN_TOUCH, nfingers > 0);
evdev_push_nfingers(sc->evdev_a, nfingers);
if (nfingers > 0)
psm_push_st_finger(sc, &f[0]);
else
evdev_push_abs(sc->evdev_a, ABS_PRESSURE, 0);
evdev_push_mouse_btn(sc->evdev_a, touchpad_buttons);
if (sc->synhw.capExtended && sc->synhw.capFourButtons) {
evdev_push_key(sc->evdev_a, BTN_FORWARD,
touchpad_buttons & MOUSE_BUTTON4DOWN);
evdev_push_key(sc->evdev_a, BTN_BACK,
touchpad_buttons & MOUSE_BUTTON5DOWN);
}
evdev_sync(sc->evdev_a);
}
#endif
ms->button = touchpad_buttons;
psmgestures(sc, &f[0], nfingers, ms);
@ -4015,7 +4505,12 @@ proc_elantech(struct psm_softc *sc, packetbuf_t *pb, mousestatus_t *ms,
((pb->ipacket[0] & 0x01) ? MOUSE_BUTTON1DOWN : 0) |
((pb->ipacket[0] & 0x02) ? MOUSE_BUTTON3DOWN : 0) |
((pb->ipacket[0] & 0x04) ? MOUSE_BUTTON2DOWN : 0);
#ifdef EVDEV_SUPPORT
evdev_push_rel(sc->evdev_r, REL_X, *x);
evdev_push_rel(sc->evdev_r, REL_Y, -*y);
evdev_push_mouse_btn(sc->evdev_r, trackpoint_button);
evdev_sync(sc->evdev_r);
#endif
ms->button = touchpad_button | trackpoint_button;
return (0);
@ -4042,6 +4537,31 @@ proc_elantech(struct psm_softc *sc, packetbuf_t *pb, mousestatus_t *ms,
((pb->ipacket[0] & 0x02) ? MOUSE_BUTTON3DOWN : 0);
}
#ifdef EVDEV_SUPPORT
if (evdev_rcpt_mask & EVDEV_RCPT_HW_MOUSE) {
for (id = 0; id < ELANTECH_MAX_FINGERS; id++) {
if (PSM_FINGER_IS_SET(f[id])) {
psm_push_mt_finger(sc, id, &f[id]);
/* Convert touch width to surface units */
evdev_push_abs(sc->evdev_a, ABS_MT_TOUCH_MAJOR,
f[id].w * sc->elanhw.dptracex);
}
if (sc->elanaction.mask & (1 << id) &&
!(mask & (1 << id)))
psm_release_mt_slot(sc->evdev_a, id);
}
evdev_push_key(sc->evdev_a, BTN_TOUCH, nfingers > 0);
evdev_push_nfingers(sc->evdev_a, nfingers);
if (nfingers > 0) {
if (PSM_FINGER_IS_SET(f[0]))
psm_push_st_finger(sc, &f[0]);
} else
evdev_push_abs(sc->evdev_a, ABS_PRESSURE, 0);
evdev_push_mouse_btn(sc->evdev_a, touchpad_button);
evdev_sync(sc->evdev_a);
}
#endif
ms->button = touchpad_button | trackpoint_button;
/* Send finger 1 position to gesture processor */
@ -4382,6 +4902,41 @@ psmsoftintr(void *arg)
break;
}
#ifdef EVDEV_SUPPORT
if (evdev_rcpt_mask & EVDEV_RCPT_HW_MOUSE &&
sc->hw.model != MOUSE_MODEL_ELANTECH &&
sc->hw.model != MOUSE_MODEL_SYNAPTICS) {
evdev_push_rel(sc->evdev_r, EV_REL, x);
evdev_push_rel(sc->evdev_r, EV_REL, -y);
switch (sc->hw.model) {
case MOUSE_MODEL_EXPLORER:
case MOUSE_MODEL_INTELLI:
case MOUSE_MODEL_NET:
case MOUSE_MODEL_NETSCROLL:
case MOUSE_MODEL_4DPLUS:
evdev_push_rel(sc->evdev_r, REL_WHEEL, -z);
break;
case MOUSE_MODEL_MOUSEMANPLUS:
case MOUSE_MODEL_4D:
switch (z) {
case 1:
case -1:
evdev_push_rel(sc->evdev_r, REL_WHEEL, -z);
break;
case 2:
case -2:
evdev_push_rel(sc->evdev_r, REL_HWHEEL, z / 2);
break;
}
break;
}
evdev_push_mouse_btn(sc->evdev_r, ms.button);
evdev_sync(sc->evdev_r);
}
#endif
/* scale values */
if (sc->mode.accelfactor >= 1) {
if (x != 0) {
@ -6494,6 +7049,9 @@ psmresume(device_t dev)
}
DRIVER_MODULE(psm, atkbdc, psm_driver, psm_devclass, 0, 0);
#ifdef EVDEV_SUPPORT
MODULE_DEPEND(psm, evdev, 1, 1, 1);
#endif
#ifdef DEV_ISA

View File

@ -280,7 +280,7 @@ enum {
#define CHIPC_PLL_TYPE1 0x2 /* 48MHz base, 3 dividers */
#define CHIPC_PLL_TYPE2 0x4 /* 48MHz, 4 dividers */
#define CHIPC_PLL_TYPE3 0x6 /* 25MHz, 2 dividers */
#define CHIPC_PLL_TYPE4 0x8 /* 48MHz, 4 dividers */
#define CHIPC_PLL_TYPE4 0x1 /* 48MHz, 4 dividers */
#define CHIPC_PLL_TYPE5 0x3 /* 25MHz, 4 dividers */
#define CHIPC_PLL_TYPE6 0x5 /* 100/200 or 120/240 only */
#define CHIPC_PLL_TYPE7 0x7 /* 25MHz, 4 dividers */

View File

@ -374,7 +374,7 @@ bhnd_pwrctl_slowclk_freq(struct bhnd_pwrctl_softc *sc, bool max_freq)
} else if (PWRCTL_QUIRK(sc, SLOWCLK_CTL)) {
div = bhnd_bus_read_4(sc->res, CHIPC_PLL_SLOWCLK_CTL);
div = CHIPC_GET_BITS(div, CHIPC_SCC_CD);
div *= 4;
div = 4 * (div + 1);
} else if (PWRCTL_QUIRK(sc, INSTACLK_CTL)) {
if (max_freq) {
div = 1;
@ -503,7 +503,10 @@ bhnd_pwrctl_setclk(struct bhnd_pwrctl_softc *sc, bhnd_clock clock)
if (bhnd_get_hwrev(sc->chipc_dev) == 10)
return (ENODEV);
scc = bhnd_bus_read_4(sc->res, CHIPC_PLL_SLOWCLK_CTL);
if (PWRCTL_QUIRK(sc, SLOWCLK_CTL))
scc = bhnd_bus_read_4(sc->res, CHIPC_PLL_SLOWCLK_CTL);
else
scc = bhnd_bus_read_4(sc->res, CHIPC_SYS_CLK_CTL);
switch (clock) {
case BHND_CLOCK_HT:
@ -520,7 +523,10 @@ bhnd_pwrctl_setclk(struct bhnd_pwrctl_softc *sc, bhnd_clock clock)
return (ENODEV);
}
bhnd_bus_write_4(sc->res, CHIPC_PLL_SLOWCLK_CTL, scc);
if (PWRCTL_QUIRK(sc, SLOWCLK_CTL))
bhnd_bus_write_4(sc->res, CHIPC_PLL_SLOWCLK_CTL, scc);
else
bhnd_bus_write_4(sc->res, CHIPC_SYS_CLK_CTL, scc);
DELAY(CHIPC_PLL_DELAY);
break;

View File

@ -117,6 +117,13 @@ __FBSDID("$FreeBSD$");
#define MAX_RX_PHYS_DSGL_SGE 32
#define DSGL_SGE_MAXLEN 65535
/*
* The adapter only supports requests with a total input or output
* length of 64k-1 or smaller. Longer requests either result in hung
* requests or incorrect results.
*/
#define MAX_REQUEST_SIZE 65535
static MALLOC_DEFINE(M_CCR, "ccr", "Chelsio T6 crypto");
struct ccr_session_hmac {
@ -412,6 +419,12 @@ ccr_hmac(struct ccr_softc *sc, uint32_t sid, struct ccr_session *s,
u_int imm_len, iopad_size;
int error, sgl_nsegs, sgl_len;
crd = crp->crp_desc;
/* Reject requests with too large of an input buffer. */
if (crd->crd_len > MAX_REQUEST_SIZE)
return (EFBIG);
axf = s->hmac.auth_hash;
/* PADs must be 128-bit aligned. */
@ -425,7 +438,6 @@ ccr_hmac(struct ccr_softc *sc, uint32_t sid, struct ccr_session *s,
hash_size_in_response = axf->hashsize;
transhdr_len = HASH_TRANSHDR_SIZE(kctx_len);
crd = crp->crp_desc;
if (ccr_use_imm_data(transhdr_len, crd->crd_len)) {
imm_len = crd->crd_len;
sgl_nsegs = 0;
@ -538,6 +550,10 @@ ccr_blkcipher(struct ccr_softc *sc, uint32_t sid, struct ccr_session *s,
(crd->crd_len % AES_BLOCK_LEN) != 0)
return (EINVAL);
/* Reject requests with too large of an input buffer. */
if (crd->crd_len > MAX_REQUEST_SIZE)
return (EFBIG);
iv_loc = IV_NOP;
if (crd->crd_flags & CRD_F_ENCRYPT) {
op_type = CHCR_ENCRYPT_OP;
@ -785,6 +801,13 @@ ccr_authenc(struct ccr_softc *sc, uint32_t sid, struct ccr_session *s,
* the hash when encrypting. For decryption it only contains
* the plain text.
*/
if (op_type == CHCR_ENCRYPT_OP) {
if (crde->crd_len + hash_size_in_response > MAX_REQUEST_SIZE)
return (EFBIG);
} else {
if (crde->crd_len > MAX_REQUEST_SIZE)
return (EFBIG);
}
sglist_reset(sc->sg_dsgl);
error = sglist_append_sglist(sc->sg_dsgl, sc->sg_crp, crde->crd_skip,
crde->crd_len);
@ -824,6 +847,17 @@ ccr_authenc(struct ccr_softc *sc, uint32_t sid, struct ccr_session *s,
} else
aad_len = 0;
input_len = aad_len + crde->crd_len;
/*
* The firmware hangs if sent a request which is a
* bit smaller than MAX_REQUEST_SIZE. In particular, the
* firmware appears to require 512 - 16 bytes of spare room
* along with the size of the hash even if the hash isn't
* included in the input buffer.
*/
if (input_len + roundup2(axf->hashsize, 16) + (512 - 16) >
MAX_REQUEST_SIZE)
return (EFBIG);
if (op_type == CHCR_DECRYPT_OP)
input_len += hash_size_in_response;
if (ccr_use_imm_data(transhdr_len, s->blkcipher.iv_len + input_len)) {
@ -1105,6 +1139,13 @@ ccr_gcm(struct ccr_softc *sc, uint32_t sid, struct ccr_session *s,
* the tag when encrypting. For decryption it only contains
* the plain text.
*/
if (op_type == CHCR_ENCRYPT_OP) {
if (crde->crd_len + hash_size_in_response > MAX_REQUEST_SIZE)
return (EFBIG);
} else {
if (crde->crd_len > MAX_REQUEST_SIZE)
return (EFBIG);
}
sglist_reset(sc->sg_dsgl);
error = sglist_append_sglist(sc->sg_dsgl, sc->sg_crp, crde->crd_skip,
crde->crd_len);
@ -1136,6 +1177,8 @@ ccr_gcm(struct ccr_softc *sc, uint32_t sid, struct ccr_session *s,
input_len = crda->crd_len + crde->crd_len;
if (op_type == CHCR_DECRYPT_OP)
input_len += hash_size_in_response;
if (input_len > MAX_REQUEST_SIZE)
return (EFBIG);
if (ccr_use_imm_data(transhdr_len, iv_len + input_len)) {
imm_len = input_len;
sgl_nsegs = 0;

View File

@ -54,10 +54,12 @@
#include <dev/iicbus/iicbus.h>
#include <dev/mii/mii.h>
#include <dev/mii/miivar.h>
#include <dev/mdio/mdio.h>
#include <dev/etherswitch/etherswitch.h>
#include <dev/etherswitch/rtl8366/rtl8366rbvar.h>
#include "mdio_if.h"
#include "iicbus_if.h"
#include "miibus_if.h"
#include "etherswitch_if.h"
@ -74,7 +76,9 @@ struct rtl8366rb_softc {
struct ifnet *ifp[RTL8366_NUM_PHYS];
struct callout callout_tick;
etherswitch_info_t info;
int chip_type; /* 0 = RTL8366RB, 1 = RTL8366SR */
int chip_type;
int phy4cpu;
int numphys;
};
#define RTL_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
@ -145,7 +149,7 @@ rtl8366rb_probe(device_t dev)
bzero(sc, sizeof(*sc));
if (smi_probe(dev) != 0)
return (ENXIO);
if(sc->chip_type == 0)
if (sc->chip_type == RTL8366RB)
device_set_desc(dev, "RTL8366RB Ethernet Switch Controller");
else
device_set_desc(dev, "RTL8366SR Ethernet Switch Controller");
@ -215,17 +219,23 @@ rtl8366rb_attach(device_t dev)
smi_read(dev, RTL8366_CVCR, &rev, RTL_WAITOK);
device_printf(dev, "rev. %d\n", rev & 0x000f);
sc->info.es_nports = RTL8366_NUM_PORTS;
sc->phy4cpu = 0;
(void) resource_int_value(device_get_name(dev), device_get_unit(dev),
"phy4cpu", &sc->phy4cpu);
sc->numphys = sc->phy4cpu ? RTL8366_NUM_PHYS - 1 : RTL8366_NUM_PHYS;
sc->info.es_nports = sc->numphys + 1;
sc->info.es_nvlangroups = RTL8366_NUM_VLANS;
sc->info.es_vlan_caps = ETHERSWITCH_VLAN_DOT1Q;
if(sc->chip_type == 0)
if (sc->chip_type == RTL8366RB)
sprintf(sc->info.es_name, "Realtek RTL8366RB");
else
sprintf(sc->info.es_name, "Realtek RTL8366SR");
/* attach miibus and phys */
/* PHYs need an interface, so we generate a dummy one */
for (i = 0; i < RTL8366_NUM_PHYS; i++) {
for (i = 0; i < sc->numphys; i++) {
sc->ifp[i] = if_alloc(IFT_ETHER);
sc->ifp[i]->if_softc = sc;
sc->ifp[i]->if_flags |= IFF_UP | IFF_BROADCAST | IFF_DRV_RUNNING
@ -263,7 +273,7 @@ rtl8366rb_detach(device_t dev)
sc = device_get_softc(dev);
for (i=0; i < RTL8366_NUM_PHYS; i++) {
for (i=0; i < sc->numphys; i++) {
if (sc->miibus[i])
device_delete_child(dev, sc->miibus[i]);
if (sc->ifp[i] != NULL)
@ -319,7 +329,7 @@ rtl833rb_miipollstat(struct rtl8366rb_softc *sc)
uint16_t value;
int portstatus;
for (i = 0; i < RTL8366_NUM_PHYS; i++) {
for (i = 0; i < sc->numphys; i++) {
mii = device_get_softc(sc->miibus[i]);
if ((i % 2) == 0) {
if (smi_read(sc->dev, RTL8366_PLSR_BASE + i/2, &value, RTL_NOWAIT) != 0) {
@ -365,7 +375,7 @@ smi_probe(device_t dev)
iicbus = device_get_parent(dev);
iicha = device_get_parent(iicbus);
for(i = 0; i < 2; ++i) {
for (i = 0; i < 2; ++i) {
iicbus_reset(iicbus, IIC_FASTEST, RTL8366_IIC_ADDR, NULL);
for (j=3; j--; ) {
IICBUS_STOP(iicha);
@ -380,7 +390,7 @@ smi_probe(device_t dev)
err = iicbus_start(iicbus, RTL8366_IIC_ADDR | RTL_IICBUS_READ, RTL_IICBUS_TIMEOUT);
if (err != 0)
goto out;
if(i == 0) {
if (i == 0) {
bytes[0] = RTL8366RB_CIR & 0xff;
bytes[1] = (RTL8366RB_CIR >> 8) & 0xff;
} else {
@ -396,22 +406,22 @@ smi_probe(device_t dev)
chipid = ((bytes[1] & 0xff) << 8) | (bytes[0] & 0xff);
if (i == 0 && chipid == RTL8366RB_CIR_ID8366RB) {
DPRINTF(dev, "chip id 0x%04x\n", chipid);
sc->chip_type = 0;
sc->chip_type = RTL8366RB;
err = 0;
break;
}
if (i == 1 && chipid == RTL8366SR_CIR_ID8366SR) {
DPRINTF(dev, "chip id 0x%04x\n", chipid);
sc->chip_type = 1;
sc->chip_type = RTL8366SR;
err = 0;
break;
}
if(i == 0) {
if (i == 0) {
iicbus_stop(iicbus);
iicbus_release_bus(iicbus, dev);
}
}
if(i == 2)
if (i == 2)
err = ENXIO;
out:
iicbus_stop(iicbus);
@ -472,7 +482,7 @@ smi_select(device_t dev, int op, int sleep)
RTL_SMI_ACQUIRED_ASSERT((struct rtl8366rb_softc *)device_get_softc(dev));
if(sc->chip_type == 1) { // RTL8366SR work around
if (sc->chip_type == RTL8366SR) { // RTL8366SR work around
// this is same work around at probe
for (int i=3; i--; )
IICBUS_STOP(device_get_parent(device_get_parent(dev)));
@ -648,13 +658,18 @@ rtl_getport(device_t dev, etherswitch_port_t *p)
ifmr = &p->es_ifmr;
if (p->es_port < 0 || p->es_port >= RTL8366_NUM_PORTS)
if (p->es_port < 0 || p->es_port >= (sc->numphys + 1))
return (ENXIO);
vlangroup = RTL8366_PVCR_GET(p->es_port,
rtl_readreg(dev, RTL8366_PVCR_REG(p->es_port)));
if (sc->phy4cpu && p->es_port == sc->numphys) {
vlangroup = RTL8366_PVCR_GET(p->es_port + 1,
rtl_readreg(dev, RTL8366_PVCR_REG(p->es_port + 1)));
} else {
vlangroup = RTL8366_PVCR_GET(p->es_port,
rtl_readreg(dev, RTL8366_PVCR_REG(p->es_port)));
}
p->es_pvid = sc->vid[vlangroup] & ETHERSWITCH_VID_MASK;
if (p->es_port < RTL8366_NUM_PHYS) {
if (p->es_port < sc->numphys) {
mii = device_get_softc(sc->miibus[p->es_port]);
ifm = &mii->mii_media;
err = ifmedia_ioctl(sc->ifp[p->es_port], &p->es_ifr, ifm, SIOCGIFMEDIA);
@ -687,10 +702,11 @@ rtl_setport(device_t dev, etherswitch_port_t *p)
int i, err, vlangroup;
struct ifmedia *ifm;
struct mii_data *mii;
int port;
sc = device_get_softc(dev);
if (p->es_port < 0 || p->es_port >= RTL8366_NUM_PORTS)
if (p->es_port < 0 || p->es_port >= (sc->numphys + 1))
return (ENXIO);
vlangroup = -1;
for (i = 0; i < RTL8366_NUM_VLANS; i++) {
@ -701,12 +717,18 @@ rtl_setport(device_t dev, etherswitch_port_t *p)
}
if (vlangroup == -1)
return (ENXIO);
err = smi_rmw(dev, RTL8366_PVCR_REG(p->es_port),
RTL8366_PVCR_VAL(p->es_port, RTL8366_PVCR_PORT_MASK),
RTL8366_PVCR_VAL(p->es_port, vlangroup), RTL_WAITOK);
if (sc->phy4cpu && p->es_port == sc->numphys) {
port = p->es_port + 1;
} else {
port = p->es_port;
}
err = smi_rmw(dev, RTL8366_PVCR_REG(port),
RTL8366_PVCR_VAL(port, RTL8366_PVCR_PORT_MASK),
RTL8366_PVCR_VAL(port, vlangroup), RTL_WAITOK);
if (err)
return (err);
if (p->es_port == RTL8366_CPU_PORT)
/* CPU Port */
if (p->es_port == sc->numphys)
return (0);
mii = device_get_softc(sc->miibus[p->es_port]);
ifm = &mii->mii_media;
@ -720,6 +742,7 @@ rtl_getvgroup(device_t dev, etherswitch_vlangroup_t *vg)
struct rtl8366rb_softc *sc;
uint16_t vmcr[3];
int i;
int member, untagged;
sc = device_get_softc(dev);
@ -727,8 +750,15 @@ rtl_getvgroup(device_t dev, etherswitch_vlangroup_t *vg)
vmcr[i] = rtl_readreg(dev, RTL8366_VMCR(i, vg->es_vlangroup));
vg->es_vid = sc->vid[vg->es_vlangroup];
vg->es_member_ports = RTL8366_VMCR_MEMBER(vmcr);
vg->es_untagged_ports = RTL8366_VMCR_UNTAG(vmcr);
member = RTL8366_VMCR_MEMBER(vmcr);
untagged = RTL8366_VMCR_UNTAG(vmcr);
if (sc->phy4cpu) {
vg->es_member_ports = ((member & 0x20) >> 1) | (member & 0x0f);
vg->es_untagged_ports = ((untagged & 0x20) >> 1) | (untagged & 0x0f);
} else {
vg->es_member_ports = member;
vg->es_untagged_ports = untagged;
}
vg->es_fid = RTL8366_VMCR_FID(vmcr);
return (0);
}
@ -738,6 +768,7 @@ rtl_setvgroup(device_t dev, etherswitch_vlangroup_t *vg)
{
struct rtl8366rb_softc *sc;
int g;
int member, untagged;
sc = device_get_softc(dev);
@ -750,16 +781,26 @@ rtl_setvgroup(device_t dev, etherswitch_vlangroup_t *vg)
sc->vid[g] |= ETHERSWITCH_VID_VALID;
rtl_writereg(dev, RTL8366_VMCR(RTL8366_VMCR_DOT1Q_REG, g),
(vg->es_vid << RTL8366_VMCR_DOT1Q_VID_SHIFT) & RTL8366_VMCR_DOT1Q_VID_MASK);
if(sc->chip_type == 0) {
if (sc->phy4cpu) {
/* add space at phy4 */
member = (vg->es_member_ports & 0x0f) |
((vg->es_member_ports & 0x10) << 1);
untagged = (vg->es_untagged_ports & 0x0f) |
((vg->es_untagged_ports & 0x10) << 1);
} else {
member = vg->es_member_ports;
untagged = vg->es_untagged_ports;
}
if (sc->chip_type == RTL8366RB) {
rtl_writereg(dev, RTL8366_VMCR(RTL8366_VMCR_MU_REG, g),
((vg->es_member_ports << RTL8366_VMCR_MU_MEMBER_SHIFT) & RTL8366_VMCR_MU_MEMBER_MASK) |
((vg->es_untagged_ports << RTL8366_VMCR_MU_UNTAG_SHIFT) & RTL8366_VMCR_MU_UNTAG_MASK));
((member << RTL8366_VMCR_MU_MEMBER_SHIFT) & RTL8366_VMCR_MU_MEMBER_MASK) |
((untagged << RTL8366_VMCR_MU_UNTAG_SHIFT) & RTL8366_VMCR_MU_UNTAG_MASK));
rtl_writereg(dev, RTL8366_VMCR(RTL8366_VMCR_FID_REG, g),
vg->es_fid);
} else {
rtl_writereg(dev, RTL8366_VMCR(RTL8366_VMCR_MU_REG, g),
((vg->es_member_ports << RTL8366_VMCR_MU_MEMBER_SHIFT) & RTL8366_VMCR_MU_MEMBER_MASK) |
((vg->es_untagged_ports << RTL8366_VMCR_MU_UNTAG_SHIFT) & RTL8366_VMCR_MU_UNTAG_MASK) |
((member << RTL8366_VMCR_MU_MEMBER_SHIFT) & RTL8366_VMCR_MU_MEMBER_MASK) |
((untagged << RTL8366_VMCR_MU_UNTAG_SHIFT) & RTL8366_VMCR_MU_UNTAG_MASK) |
((vg->es_fid << RTL8366_VMCR_FID_FID_SHIFT) & RTL8366_VMCR_FID_FID_MASK));
}
return (0);
@ -886,6 +927,10 @@ static device_method_t rtl8366rb_methods[] = {
DEVMETHOD(miibus_readreg, rtl_readphy),
DEVMETHOD(miibus_writereg, rtl_writephy),
/* MDIO interface */
DEVMETHOD(mdio_readreg, rtl_readphy),
DEVMETHOD(mdio_writereg, rtl_writephy),
/* etherswitch interface */
DEVMETHOD(etherswitch_getconf, rtl_getconf),
DEVMETHOD(etherswitch_getinfo, rtl_getinfo),
@ -907,6 +952,7 @@ static devclass_t rtl8366rb_devclass;
DRIVER_MODULE(rtl8366rb, iicbus, rtl8366rb_driver, rtl8366rb_devclass, 0, 0);
DRIVER_MODULE(miibus, rtl8366rb, miibus_driver, miibus_devclass, 0, 0);
DRIVER_MODULE(mdio, rtl8366rb, mdio_driver, mdio_devclass, 0, 0);
DRIVER_MODULE(etherswitch, rtl8366rb, etherswitch_driver, etherswitch_devclass, 0, 0);
MODULE_VERSION(rtl8366rb, 1);
MODULE_DEPEND(rtl8366rb, iicbus, 1, 1, 1); /* XXX which versions? */

View File

@ -30,6 +30,9 @@
#ifndef _DEV_ETHERSWITCH_RTL8366RBVAR_H_
#define _DEV_ETHERSWITCH_RTL8366RBVAR_H_
#define RTL8366RB 0
#define RTL8366SR 1
#define RTL8366_IIC_ADDR 0xa8
#define RTL_IICBUS_TIMEOUT 100 /* us */
#define RTL_IICBUS_READ 1
@ -173,9 +176,7 @@
(0x8000 | (1 << (((phy) & 0x1f) + 9)) | (((page) & (sc->chip_type == 0 ? 0xf : 0x7)) << 5) | ((reg) & 0x1f))
/* general characteristics of the chip */
#define RTL8366_CPU_PORT 5
#define RTL8366_NUM_PORTS 6
#define RTL8366_NUM_PHYS (RTL8366_NUM_PORTS-1)
#define RTL8366_NUM_PHYS 5
#define RTL8366_NUM_VLANS 16
#define RTL8366_NUM_PHY_REG 32

View File

@ -91,9 +91,9 @@ static struct ieee80211vap *rtwn_vap_create(struct ieee80211com *,
static void rtwn_vap_delete(struct ieee80211vap *);
static int rtwn_read_chipid(struct rtwn_softc *);
static int rtwn_ioctl_reset(struct ieee80211vap *, u_long);
#ifndef RTWN_WITHOUT_UCODE
static void rtwn_set_media_status(struct rtwn_softc *,
union sec_param *);
#ifndef RTWN_WITHOUT_UCODE
static int rtwn_tx_fwpkt_check(struct rtwn_softc *,
struct ieee80211vap *);
static int rtwn_construct_nulldata(struct rtwn_softc *,
@ -703,13 +703,13 @@ rtwn_ioctl_reset(struct ieee80211vap *vap, u_long cmd)
return (error);
}
#ifndef RTWN_WITHOUT_UCODE
static void
rtwn_set_media_status(struct rtwn_softc *sc, union sec_param *data)
{
sc->sc_set_media_status(sc, data->macid);
}
#ifndef RTWN_WITHOUT_UCODE
static int
rtwn_tx_fwpkt_check(struct rtwn_softc *sc, struct ieee80211vap *vap)
{
@ -1743,11 +1743,9 @@ rtwn_newassoc(struct ieee80211_node *ni, int isnew __unused)
return;
}
#ifndef RTWN_WITHOUT_UCODE
/* Notify firmware. */
id |= RTWN_MACID_VALID;
rtwn_cmd_sleepable(sc, &id, sizeof(id), rtwn_set_media_status);
#endif
}
static void
@ -1759,10 +1757,8 @@ rtwn_node_free(struct ieee80211_node *ni)
RTWN_NT_LOCK(sc);
if (un->id != RTWN_MACID_UNDEFINED) {
sc->node_list[un->id] = NULL;
#ifndef RTWN_WITHOUT_UCODE
rtwn_cmd_sleepable(sc, &un->id, sizeof(un->id),
rtwn_set_media_status);
#endif
}
RTWN_NT_UNLOCK(sc);

View File

@ -141,11 +141,13 @@ r92eu_attach(struct rtwn_usb_softc *uc)
sc->sc_vap_preattach = rtwn_nop_softc_vap;
sc->sc_postattach = rtwn_nop_softc;
sc->sc_detach_private = r92e_detach_private;
sc->sc_set_media_status = r92e_set_media_status;
#ifndef RTWN_WITHOUT_UCODE
sc->sc_set_media_status = r92e_set_media_status;
sc->sc_set_rsvd_page = r88e_set_rsvd_page;
sc->sc_set_pwrmode = r92e_set_pwrmode;
sc->sc_set_rssi = rtwn_nop_softc; /* XXX TODO? */
#else
sc->sc_set_media_status = rtwn_nop_softc_int;
#endif
sc->sc_beacon_init = r12a_beacon_init;
sc->sc_beacon_enable = r92c_beacon_enable;

View File

@ -127,6 +127,7 @@ static const struct pci_id pci_ns8250_ids[] = {
24 * DEFAULT_RCLK, 2 },
{ 0x8086, 0x0f0c, 0xffff, 0, "Intel ValleyView LPIO1 HSUART#2", 0x10,
24 * DEFAULT_RCLK, 2 },
{ 0x8086, 0x108f, 0xffff, 0, "Intel AMT - SOL", 0x10 },
{ 0x8086, 0x1c3d, 0xffff, 0, "Intel AMT - KT Controller", 0x10 },
{ 0x8086, 0x1d3d, 0xffff, 0, "Intel C600/X79 Series Chipset KT Controller", 0x10 },
{ 0x8086, 0x1e3d, 0xffff, 0, "Intel Panther Point KT Controller", 0x10 },

521
sys/fs/ext2fs/ext2_acl.c Normal file
View File

@ -0,0 +1,521 @@
/*-
* Copyright (c) 2017, Fedor Uporov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/vnode.h>
#include <sys/bio.h>
#include <sys/buf.h>
#include <sys/endian.h>
#include <sys/conf.h>
#include <sys/mount.h>
#include <sys/extattr.h>
#include <fs/ext2fs/fs.h>
#include <fs/ext2fs/ext2fs.h>
#include <fs/ext2fs/inode.h>
#include <fs/ext2fs/ext2_acl.h>
#include <fs/ext2fs/ext2_extattr.h>
#include <fs/ext2fs/ext2_extern.h>
#include <fs/ext2fs/ext2_dinode.h>
#include <fs/ext2fs/ext2_mount.h>
void
ext2_sync_acl_from_inode(struct inode *ip, struct acl *acl)
{
struct acl_entry *acl_mask, *acl_group_obj;
int i;
/*
* Update ACL_USER_OBJ, ACL_OTHER, but simply identify ACL_MASK
* and ACL_GROUP_OBJ for use after we know whether ACL_MASK is
* present.
*/
acl_mask = NULL;
acl_group_obj = NULL;
for (i = 0; i < acl->acl_cnt; i++) {
switch (acl->acl_entry[i].ae_tag) {
case ACL_USER_OBJ:
acl->acl_entry[i].ae_perm = acl_posix1e_mode_to_perm(
ACL_USER_OBJ, ip->i_mode);
acl->acl_entry[i].ae_id = ACL_UNDEFINED_ID;
break;
case ACL_GROUP_OBJ:
acl_group_obj = &acl->acl_entry[i];
acl->acl_entry[i].ae_id = ACL_UNDEFINED_ID;
break;
case ACL_OTHER:
acl->acl_entry[i].ae_perm = acl_posix1e_mode_to_perm(
ACL_OTHER, ip->i_mode);
acl->acl_entry[i].ae_id = ACL_UNDEFINED_ID;
break;
case ACL_MASK:
acl_mask = &acl->acl_entry[i];
acl->acl_entry[i].ae_id = ACL_UNDEFINED_ID;
break;
case ACL_USER:
case ACL_GROUP:
break;
default:
panic("ext2_sync_acl_from_inode(): bad ae_tag");
}
}
if (acl_group_obj == NULL)
panic("ext2_sync_acl_from_inode(): no ACL_GROUP_OBJ");
if (acl_mask == NULL) {
/*
* There is no ACL_MASK, so update ACL_GROUP_OBJ.
*/
acl_group_obj->ae_perm = acl_posix1e_mode_to_perm(
ACL_GROUP_OBJ, ip->i_mode);
} else {
/*
* Update the ACL_MASK entry instead of ACL_GROUP_OBJ.
*/
acl_mask->ae_perm = acl_posix1e_mode_to_perm(ACL_GROUP_OBJ,
ip->i_mode);
}
}
static void
ext2_sync_inode_from_acl(struct acl *acl, struct inode *ip)
{
ip->i_mode &= ACL_PRESERVE_MASK;
ip->i_mode |= acl_posix1e_acl_to_mode(acl);
}
/*
* Convert from filesystem to in-memory representation.
*/
static int
ext4_acl_from_disk(char *value, size_t size, struct acl *acl)
{
const char *end = value + size;
int n, count, s;
if (((struct ext2_acl_header *)value)->a_version != EXT4_ACL_VERSION)
return (EINVAL);
if (!value || size < sizeof(struct ext2_acl_header))
return (EINVAL);
s = size - sizeof(struct ext2_acl_header);
s -= 4 * sizeof(struct ext2_acl_entry_short);
if (s < 0)
if ((size - sizeof(struct ext2_acl_header)) %
sizeof(struct ext2_acl_entry_short))
count = -1;
else
count = (size - sizeof(struct ext2_acl_header)) /
sizeof(struct ext2_acl_entry_short);
else
if (s % sizeof(struct ext2_acl_entry))
count = -1;
else
count = s / sizeof(struct ext2_acl_entry) + 4;
if (count <= 0 || count > acl->acl_maxcnt)
return (EINVAL);
value = value + sizeof(struct ext2_acl_header);
for (n = 0; n < count; n++) {
struct ext2_acl_entry *entry = (struct ext2_acl_entry *)value;
if ((char *)value + sizeof(struct ext2_acl_entry_short) > end)
return (EINVAL);
acl->acl_entry[n].ae_tag = entry->ae_tag;
acl->acl_entry[n].ae_perm = entry->ae_perm;
switch (acl->acl_entry[n].ae_tag) {
case ACL_USER_OBJ:
case ACL_GROUP_OBJ:
case ACL_MASK:
case ACL_OTHER:
value = (char *)value + sizeof(struct ext2_acl_entry_short);
break;
case ACL_USER:
value = (char *)value + sizeof(struct ext2_acl_entry);
if ((char *)value > end)
return (EINVAL);
acl->acl_entry[n].ae_id = entry->ae_id;
break;
case ACL_GROUP:
value = (char *)value + sizeof(struct ext2_acl_entry);
if ((char *)value > end)
return (EINVAL);
acl->acl_entry[n].ae_id = entry->ae_id;
break;
default:
return (EINVAL);
}
}
if (value != end)
return (EINVAL);
acl->acl_cnt = count;
return (0);
}
static int
ext2_getacl_posix1e(struct vop_getacl_args *ap)
{
int attrnamespace;
const char *attrname;
char *value;
int len;
int error;
switch (ap->a_type) {
case ACL_TYPE_DEFAULT:
attrnamespace = POSIX1E_ACL_DEFAULT_EXTATTR_NAMESPACE;
attrname = POSIX1E_ACL_DEFAULT_EXTATTR_NAME;
break;
case ACL_TYPE_ACCESS:
attrnamespace = POSIX1E_ACL_ACCESS_EXTATTR_NAMESPACE;
attrname = POSIX1E_ACL_ACCESS_EXTATTR_NAME;
break;
default:
return (EINVAL);
}
len = sizeof(*ap->a_aclp) + sizeof(struct ext2_acl_header);
value = malloc(len, M_ACL, M_WAITOK);
if (!value)
return (ENOMEM);
error = vn_extattr_get(ap->a_vp, IO_NODELOCKED, attrnamespace, attrname,
&len, value, ap->a_td);
switch (error) {
case ENOATTR:
switch (ap->a_type) {
case ACL_TYPE_ACCESS:
ap->a_aclp->acl_cnt = 3;
ap->a_aclp->acl_entry[0].ae_tag = ACL_USER_OBJ;
ap->a_aclp->acl_entry[0].ae_id = ACL_UNDEFINED_ID;
ap->a_aclp->acl_entry[0].ae_perm = ACL_PERM_NONE;
ap->a_aclp->acl_entry[1].ae_tag = ACL_GROUP_OBJ;
ap->a_aclp->acl_entry[1].ae_id = ACL_UNDEFINED_ID;
ap->a_aclp->acl_entry[1].ae_perm = ACL_PERM_NONE;
ap->a_aclp->acl_entry[2].ae_tag = ACL_OTHER;
ap->a_aclp->acl_entry[2].ae_id = ACL_UNDEFINED_ID;
ap->a_aclp->acl_entry[2].ae_perm = ACL_PERM_NONE;
break;
case ACL_TYPE_DEFAULT:
ap->a_aclp->acl_cnt = 0;
break;
}
case 0:
if (!error) {
error = ext4_acl_from_disk(value, len, ap->a_aclp);
if (error)
goto out;
}
if (error == ENOATTR)
error = 0;
if (ap->a_type == ACL_TYPE_ACCESS)
ext2_sync_acl_from_inode(VTOI(ap->a_vp), ap->a_aclp);
default:
break;
}
out:
free(value, M_TEMP);
return (error);
}
int
ext2_getacl(struct vop_getacl_args *ap)
{
if (((ap->a_vp->v_mount->mnt_flag & MNT_ACLS) == 0) ||
((ap->a_vp->v_mount->mnt_flag & MNT_NFS4ACLS) == 1))
return (EOPNOTSUPP);
if (ap->a_type == ACL_TYPE_NFS4)
return (ENOTSUP);
return (ext2_getacl_posix1e(ap));
}
/*
* Convert from in-memory to filesystem representation.
*/
static int
ext4_acl_to_disk(const struct acl *acl, size_t *size, char *value)
{
struct ext2_acl_header *ext_acl;
int disk_size;
char *e;
size_t n;
if (acl->acl_cnt <= 4)
disk_size = sizeof(struct ext2_acl_header) +
acl->acl_cnt * sizeof(struct ext2_acl_entry_short);
else
disk_size = sizeof(struct ext2_acl_header) +
4 * sizeof(struct ext2_acl_entry_short) +
(acl->acl_cnt - 4) * sizeof(struct ext2_acl_entry);
if (disk_size > *size)
return (EINVAL);
*size = disk_size;
ext_acl = (struct ext2_acl_header *)value;
ext_acl->a_version = EXT4_ACL_VERSION;
e = (char *)ext_acl + sizeof(struct ext2_acl_header);
for (n = 0; n < acl->acl_cnt; n++) {
const struct acl_entry *acl_e = &acl->acl_entry[n];
struct ext2_acl_entry *entry = (struct ext2_acl_entry *)e;
entry->ae_tag = acl_e->ae_tag;
entry->ae_perm = acl_e->ae_perm;
switch (acl_e->ae_tag) {
case ACL_USER:
entry->ae_id = acl_e->ae_id;
e += sizeof(struct ext2_acl_entry);
break;
case ACL_GROUP:
entry->ae_id = acl_e->ae_id;
e += sizeof(struct ext2_acl_entry);
break;
case ACL_USER_OBJ:
case ACL_GROUP_OBJ:
case ACL_MASK:
case ACL_OTHER:
e += sizeof(struct ext2_acl_entry_short);
break;
default:
return (EINVAL);
}
}
return (0);
}
static int
ext2_setacl_posix1e(struct vop_setacl_args *ap)
{
struct inode *ip = VTOI(ap->a_vp);
char *value;
size_t len;
int error;
if ((ap->a_vp->v_mount->mnt_flag & MNT_ACLS) == 0)
return (EINVAL);
/*
* If this is a set operation rather than a delete operation,
* invoke VOP_ACLCHECK() on the passed ACL to determine if it is
* valid for the target. This will include a check on ap->a_type.
*/
if (ap->a_aclp != NULL) {
/*
* Set operation.
*/
error = VOP_ACLCHECK(ap->a_vp, ap->a_type, ap->a_aclp,
ap->a_cred, ap->a_td);
if (error)
return (error);
} else {
/*
* Delete operation.
* POSIX.1e allows only deletion of the default ACL on a
* directory (ACL_TYPE_DEFAULT).
*/
if (ap->a_type != ACL_TYPE_DEFAULT)
return (EINVAL);
if (ap->a_vp->v_type != VDIR)
return (ENOTDIR);
}
if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY)
return (EROFS);
/*
* Authorize the ACL operation.
*/
if (ip->i_flags & (IMMUTABLE | APPEND))
return (EPERM);
/*
* Must hold VADMIN (be file owner) or have appropriate privilege.
*/
if ((error = VOP_ACCESS(ap->a_vp, VADMIN, ap->a_cred, ap->a_td)))
return (error);
switch (ap->a_type) {
case ACL_TYPE_ACCESS:
len = sizeof(*ap->a_aclp) + sizeof(struct ext2_acl_header);
value = malloc(len, M_ACL, M_WAITOK | M_ZERO);
error = ext4_acl_to_disk(ap->a_aclp, &len, value);
if (error == 0)
error = vn_extattr_set(ap->a_vp, IO_NODELOCKED,
POSIX1E_ACL_ACCESS_EXTATTR_NAMESPACE,
POSIX1E_ACL_ACCESS_EXTATTR_NAME, len,
value, ap->a_td);
free(value, M_ACL);
break;
case ACL_TYPE_DEFAULT:
if (ap->a_aclp == NULL) {
error = vn_extattr_rm(ap->a_vp, IO_NODELOCKED,
POSIX1E_ACL_DEFAULT_EXTATTR_NAMESPACE,
POSIX1E_ACL_DEFAULT_EXTATTR_NAME, ap->a_td);
/*
* Attempting to delete a non-present default ACL
* will return success for portability purposes.
* (TRIX)
*
* XXX: Note that since we can't distinguish
* "that EA is not supported" from "that EA is not
* defined", the success case here overlaps the
* the ENOATTR->EOPNOTSUPP case below.
*/
if (error == ENOATTR)
error = 0;
} else {
len = sizeof(*ap->a_aclp) + sizeof(struct ext2_acl_header);
value = malloc(len, M_ACL, M_WAITOK | M_ZERO);
error = ext4_acl_to_disk(ap->a_aclp, &len, value);
if (error == 0)
error = vn_extattr_set(ap->a_vp, IO_NODELOCKED,
POSIX1E_ACL_DEFAULT_EXTATTR_NAMESPACE,
POSIX1E_ACL_DEFAULT_EXTATTR_NAME, len,
value, ap->a_td);
free(value, M_ACL);
}
break;
default:
error = EINVAL;
}
/*
* Map lack of attribute definition in UFS_EXTATTR into lack of
* support for ACLs on the filesystem.
*/
if (error == ENOATTR)
return (EOPNOTSUPP);
if (error != 0)
return (error);
if (ap->a_type == ACL_TYPE_ACCESS) {
/*
* Now that the EA is successfully updated, update the
* inode and mark it as changed.
*/
ext2_sync_inode_from_acl(ap->a_aclp, ip);
ip->i_flag |= IN_CHANGE;
error = ext2_update(ip->i_vnode, 1);
}
VN_KNOTE_UNLOCKED(ap->a_vp, NOTE_ATTRIB);
return (error);
}
int
ext2_setacl(struct vop_setacl_args *ap)
{
if (((ap->a_vp->v_mount->mnt_flag & MNT_ACLS) == 0) ||
((ap->a_vp->v_mount->mnt_flag & MNT_NFS4ACLS) == 1))
return (EOPNOTSUPP);
if (ap->a_type == ACL_TYPE_NFS4)
return (ENOTSUP);
return (ext2_setacl_posix1e(ap));
}
/*
* Check the validity of an ACL for a file.
*/
int
ext2_aclcheck(struct vop_aclcheck_args *ap)
{
if (((ap->a_vp->v_mount->mnt_flag & MNT_ACLS) == 0) ||
((ap->a_vp->v_mount->mnt_flag & MNT_NFS4ACLS) == 1))
return (EOPNOTSUPP);
if (ap->a_type == ACL_TYPE_NFS4)
return (ENOTSUP);
if ((ap->a_vp->v_mount->mnt_flag & MNT_ACLS) == 0)
return (EINVAL);
/*
* Verify we understand this type of ACL, and that it applies
* to this kind of object.
* Rely on the acl_posix1e_check() routine to verify the contents.
*/
switch (ap->a_type) {
case ACL_TYPE_ACCESS:
break;
case ACL_TYPE_DEFAULT:
if (ap->a_vp->v_type != VDIR)
return (EINVAL);
break;
default:
return (EINVAL);
}
return (acl_posix1e_check(ap->a_aclp));
}

55
sys/fs/ext2fs/ext2_acl.h Normal file
View File

@ -0,0 +1,55 @@
/*-
* Copyright (c) 2017, Fedor Uporov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _FS_EXT2FS_EXT2_ACL_H_
#define _FS_EXT2FS_EXT2_ACL_H_
#define EXT4_ACL_VERSION 0x0001
struct ext2_acl_entry {
int16_t ae_tag;
int16_t ae_perm;
int32_t ae_id;
};
struct ext2_acl_entry_short {
int16_t ae_tag;
int16_t ae_perm;
};
struct ext2_acl_header {
int32_t a_version;
};
void ext2_sync_acl_from_inode(struct inode *ip, struct acl *acl);
int ext2_getacl(struct vop_getacl_args *);
int ext2_setacl(struct vop_setacl_args *);
int ext2_aclcheck(struct vop_aclcheck_args *);
#endif /* !_FS_EXT2FS_EXT2_ACL_H_ */

View File

@ -46,35 +46,92 @@
#include <fs/ext2fs/ext2_extattr.h>
#include <fs/ext2fs/ext2_extern.h>
static int
ext2_extattr_index_to_bsd(int index)
ext2_extattr_attrnamespace_to_bsd(int attrnamespace)
{
switch (index) {
case EXT4_XATTR_INDEX_SYSTEM:
return (EXTATTR_NAMESPACE_SYSTEM);
case EXT4_XATTR_INDEX_USER:
return (EXTATTR_NAMESPACE_USER);
switch (attrnamespace) {
case EXT4_XATTR_INDEX_SYSTEM:
return (EXTATTR_NAMESPACE_SYSTEM);
case EXT4_XATTR_INDEX_USER:
return (EXTATTR_NAMESPACE_USER);
case EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT:
return (POSIX1E_ACL_DEFAULT_EXTATTR_NAMESPACE);
case EXT4_XATTR_INDEX_POSIX_ACL_ACCESS:
return (POSIX1E_ACL_ACCESS_EXTATTR_NAMESPACE);
}
return (EXTATTR_NAMESPACE_EMPTY);
}
static int
ext2_extattr_index_to_linux(int index)
static const char *
ext2_extattr_name_to_bsd(int attrnamespace, const char *name, int* name_len)
{
switch (index) {
case EXTATTR_NAMESPACE_SYSTEM:
return (EXT4_XATTR_INDEX_SYSTEM);
case EXTATTR_NAMESPACE_USER:
return (EXT4_XATTR_INDEX_USER);
if (attrnamespace == EXT4_XATTR_INDEX_SYSTEM)
return (name);
else if (attrnamespace == EXT4_XATTR_INDEX_USER)
return (name);
else if (attrnamespace == EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT) {
*name_len = strlen(POSIX1E_ACL_DEFAULT_EXTATTR_NAME);
return (POSIX1E_ACL_DEFAULT_EXTATTR_NAME);
} else if (attrnamespace == EXT4_XATTR_INDEX_POSIX_ACL_ACCESS) {
*name_len = strlen(POSIX1E_ACL_ACCESS_EXTATTR_NAME);
return (POSIX1E_ACL_ACCESS_EXTATTR_NAME);
}
/*
* XXX: Not all linux namespaces are mapped to bsd for now,
* return NULL, which will be converted to ENOTSUP on upper layer.
*/
#ifdef EXT2FS_DEBUG
printf("can not convert ext2fs name to bsd: namespace=%d\n", attrnamespace);
#endif /* DEBUG */
return (NULL);
}
static int
ext2_extattr_attrnamespace_to_linux(int attrnamespace, const char *name)
{
if (attrnamespace == POSIX1E_ACL_DEFAULT_EXTATTR_NAMESPACE &&
!strcmp(name, POSIX1E_ACL_DEFAULT_EXTATTR_NAME))
return (EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT);
if (attrnamespace == POSIX1E_ACL_ACCESS_EXTATTR_NAMESPACE &&
!strcmp(name, POSIX1E_ACL_ACCESS_EXTATTR_NAME))
return (EXT4_XATTR_INDEX_POSIX_ACL_ACCESS);
switch (attrnamespace) {
case EXTATTR_NAMESPACE_SYSTEM:
return (EXT4_XATTR_INDEX_SYSTEM);
case EXTATTR_NAMESPACE_USER:
return (EXT4_XATTR_INDEX_USER);
}
/*
* In this case namespace conversion should be unique,
* so this point is unreachable.
*/
return (-1);
}
static const char *
ext2_extattr_name_to_linux(int attrnamespace, const char *name)
{
if (attrnamespace == POSIX1E_ACL_DEFAULT_EXTATTR_NAMESPACE ||
attrnamespace == POSIX1E_ACL_ACCESS_EXTATTR_NAMESPACE)
return ("");
else
return (name);
}
int
ext2_extattr_valid_attrname(int attrnamespace, const char *attrname)
{
@ -114,6 +171,8 @@ ext2_extattr_inode_list(struct inode *ip, int attrnamespace,
struct buf *bp;
struct ext2fs_extattr_dinode_header *header;
struct ext2fs_extattr_entry *entry;
const char *attr_name;
int name_len;
int error;
fs = ip->i_e2fs;
@ -147,17 +206,26 @@ ext2_extattr_inode_list(struct inode *ip, int attrnamespace,
for (entry = EXT2_IFIRST(header); !EXT2_IS_LAST_ENTRY(entry);
entry = EXT2_EXTATTR_NEXT(entry)) {
if (ext2_extattr_index_to_bsd(entry->e_name_index) != attrnamespace)
if (ext2_extattr_attrnamespace_to_bsd(entry->e_name_index) !=
attrnamespace)
continue;
name_len = entry->e_name_len;
attr_name = ext2_extattr_name_to_bsd(entry->e_name_index,
entry->e_name, &name_len);
if (!attr_name) {
brelse(bp);
return (ENOTSUP);
}
if (uio == NULL)
*size += entry->e_name_len + 1;
*size += name_len + 1;
else {
char *attr_name = malloc(entry->e_name_len + 1, M_TEMP, M_WAITOK);
attr_name[0] = entry->e_name_len;
memcpy(&attr_name[1], entry->e_name, entry->e_name_len);
error = uiomove(attr_name, entry->e_name_len + 1, uio);
free(attr_name, M_TEMP);
char *name = malloc(name_len + 1, M_TEMP, M_WAITOK);
name[0] = name_len;
memcpy(&name[1], attr_name, name_len);
error = uiomove(name, name_len + 1, uio);
free(name, M_TEMP);
if (error)
break;
}
@ -176,6 +244,8 @@ ext2_extattr_block_list(struct inode *ip, int attrnamespace,
struct buf *bp;
struct ext2fs_extattr_header *header;
struct ext2fs_extattr_entry *entry;
const char *attr_name;
int name_len;
int error;
fs = ip->i_e2fs;
@ -202,17 +272,26 @@ ext2_extattr_block_list(struct inode *ip, int attrnamespace,
for (entry = EXT2_FIRST_ENTRY(bp); !EXT2_IS_LAST_ENTRY(entry);
entry = EXT2_EXTATTR_NEXT(entry)) {
if (ext2_extattr_index_to_bsd(entry->e_name_index) != attrnamespace)
if (ext2_extattr_attrnamespace_to_bsd(entry->e_name_index) !=
attrnamespace)
continue;
name_len = entry->e_name_len;
attr_name = ext2_extattr_name_to_bsd(entry->e_name_index,
entry->e_name, &name_len);
if (!attr_name) {
brelse(bp);
return (ENOTSUP);
}
if (uio == NULL)
*size += entry->e_name_len + 1;
*size += name_len + 1;
else {
char *attr_name = malloc(entry->e_name_len + 1, M_TEMP, M_WAITOK);
attr_name[0] = entry->e_name_len;
memcpy(&attr_name[1], entry->e_name, entry->e_name_len);
error = uiomove(attr_name, entry->e_name_len + 1, uio);
free(attr_name, M_TEMP);
char *name = malloc(name_len + 1, M_TEMP, M_WAITOK);
name[0] = name_len;
memcpy(&name[1], attr_name, name_len);
error = uiomove(name, name_len + 1, uio);
free(name, M_TEMP);
if (error)
break;
}
@ -231,6 +310,8 @@ ext2_extattr_inode_get(struct inode *ip, int attrnamespace,
struct buf *bp;
struct ext2fs_extattr_dinode_header *header;
struct ext2fs_extattr_entry *entry;
const char *attr_name;
int name_len;
int error;
fs = ip->i_e2fs;
@ -264,11 +345,20 @@ ext2_extattr_inode_get(struct inode *ip, int attrnamespace,
for (entry = EXT2_IFIRST(header); !EXT2_IS_LAST_ENTRY(entry);
entry = EXT2_EXTATTR_NEXT(entry)) {
if (ext2_extattr_index_to_bsd(entry->e_name_index) != attrnamespace)
if (ext2_extattr_attrnamespace_to_bsd(entry->e_name_index) !=
attrnamespace)
continue;
if (strlen(name) == entry->e_name_len &&
0 == strncmp(entry->e_name, name, entry->e_name_len)) {
name_len = entry->e_name_len;
attr_name = ext2_extattr_name_to_bsd(entry->e_name_index,
entry->e_name, &name_len);
if (!attr_name) {
brelse(bp);
return (ENOTSUP);
}
if (strlen(name) == name_len &&
0 == strncmp(attr_name, name, name_len)) {
if (uio == NULL)
*size += entry->e_value_size;
else {
@ -294,6 +384,8 @@ ext2_extattr_block_get(struct inode *ip, int attrnamespace,
struct buf *bp;
struct ext2fs_extattr_header *header;
struct ext2fs_extattr_entry *entry;
const char *attr_name;
int name_len;
int error;
fs = ip->i_e2fs;
@ -320,11 +412,20 @@ ext2_extattr_block_get(struct inode *ip, int attrnamespace,
for (entry = EXT2_FIRST_ENTRY(bp); !EXT2_IS_LAST_ENTRY(entry);
entry = EXT2_EXTATTR_NEXT(entry)) {
if (ext2_extattr_index_to_bsd(entry->e_name_index) != attrnamespace)
if (ext2_extattr_attrnamespace_to_bsd(entry->e_name_index) !=
attrnamespace)
continue;
if (strlen(name) == entry->e_name_len &&
0 == strncmp(entry->e_name, name, entry->e_name_len)) {
name_len = entry->e_name_len;
attr_name = ext2_extattr_name_to_bsd(entry->e_name_index,
entry->e_name, &name_len);
if (!attr_name) {
brelse(bp);
return (ENOTSUP);
}
if (strlen(name) == name_len &&
0 == strncmp(attr_name, name, name_len)) {
if (uio == NULL)
*size += entry->e_value_size;
else {
@ -411,6 +512,8 @@ ext2_extattr_inode_delete(struct inode *ip, int attrnamespace, const char *name)
struct buf *bp;
struct ext2fs_extattr_dinode_header *header;
struct ext2fs_extattr_entry *entry;
const char *attr_name;
int name_len;
int error;
fs = ip->i_e2fs;
@ -444,9 +547,20 @@ ext2_extattr_inode_delete(struct inode *ip, int attrnamespace, const char *name)
/* If I am last entry, just make magic zero */
entry = EXT2_IFIRST(header);
if (EXT2_IS_LAST_ENTRY(EXT2_EXTATTR_NEXT(entry))) {
if (strlen(name) == entry->e_name_len &&
0 == strncmp(entry->e_name, name, entry->e_name_len)) {
if ((EXT2_IS_LAST_ENTRY(EXT2_EXTATTR_NEXT(entry))) &&
(ext2_extattr_attrnamespace_to_bsd(entry->e_name_index) ==
attrnamespace)) {
name_len = entry->e_name_len;
attr_name = ext2_extattr_name_to_bsd(entry->e_name_index,
entry->e_name, &name_len);
if (!attr_name) {
brelse(bp);
return (ENOTSUP);
}
if (strlen(name) == name_len &&
0 == strncmp(attr_name, name, name_len)) {
memset(header, 0, sizeof(struct ext2fs_extattr_dinode_header));
return (bwrite(bp));
@ -455,11 +569,20 @@ ext2_extattr_inode_delete(struct inode *ip, int attrnamespace, const char *name)
for (entry = EXT2_IFIRST(header); !EXT2_IS_LAST_ENTRY(entry);
entry = EXT2_EXTATTR_NEXT(entry)) {
if (ext2_extattr_index_to_bsd(entry->e_name_index) != attrnamespace)
if (ext2_extattr_attrnamespace_to_bsd(entry->e_name_index) !=
attrnamespace)
continue;
if (strlen(name) == entry->e_name_len &&
0 == strncmp(entry->e_name, name, entry->e_name_len)) {
name_len = entry->e_name_len;
attr_name = ext2_extattr_name_to_bsd(entry->e_name_index,
entry->e_name, &name_len);
if (!attr_name) {
brelse(bp);
return (ENOTSUP);
}
if (strlen(name) == name_len &&
0 == strncmp(attr_name, name, name_len)) {
ext2_extattr_delete_entry((char *)EXT2_IFIRST(header),
EXT2_IFIRST(header), entry,
(char *)dinode + EXT2_INODE_SIZE(fs));
@ -521,6 +644,8 @@ ext2_extattr_block_delete(struct inode *ip, int attrnamespace, const char *name)
struct buf *bp;
struct ext2fs_extattr_header *header;
struct ext2fs_extattr_entry *entry;
const char *attr_name;
int name_len;
int error;
fs = ip->i_e2fs;
@ -555,9 +680,20 @@ ext2_extattr_block_delete(struct inode *ip, int attrnamespace, const char *name)
/* If I am last entry, clean me and free the block */
entry = EXT2_FIRST_ENTRY(bp);
if (EXT2_IS_LAST_ENTRY(EXT2_EXTATTR_NEXT(entry))) {
if (strlen(name) == entry->e_name_len &&
0 == strncmp(entry->e_name, name, entry->e_name_len)) {
if (EXT2_IS_LAST_ENTRY(EXT2_EXTATTR_NEXT(entry)) &&
(ext2_extattr_attrnamespace_to_bsd(entry->e_name_index) ==
attrnamespace)) {
name_len = entry->e_name_len;
attr_name = ext2_extattr_name_to_bsd(entry->e_name_index,
entry->e_name, &name_len);
if (!attr_name) {
brelse(bp);
return (ENOTSUP);
}
if (strlen(name) == name_len &&
0 == strncmp(attr_name, name, name_len)) {
ip->i_blocks -= btodb(fs->e2fs_bsize);
ext2_blkfree(ip, ip->i_facl, fs->e2fs_bsize);
ip->i_facl = 0;
@ -570,11 +706,20 @@ ext2_extattr_block_delete(struct inode *ip, int attrnamespace, const char *name)
for (entry = EXT2_FIRST_ENTRY(bp); !EXT2_IS_LAST_ENTRY(entry);
entry = EXT2_EXTATTR_NEXT(entry)) {
if (ext2_extattr_index_to_bsd(entry->e_name_index) != attrnamespace)
if (ext2_extattr_attrnamespace_to_bsd(entry->e_name_index) !=
attrnamespace)
continue;
if (strlen(name) == entry->e_name_len &&
0 == strncmp(entry->e_name, name, entry->e_name_len)) {
name_len = entry->e_name_len;
attr_name = ext2_extattr_name_to_bsd(entry->e_name_index,
entry->e_name, &name_len);
if (!attr_name) {
brelse(bp);
return (ENOTSUP);
}
if (strlen(name) == name_len &&
0 == strncmp(attr_name, name, name_len)) {
ext2_extattr_delete_entry(bp->b_data,
EXT2_FIRST_ENTRY(bp), entry,
bp->b_data + bp->b_bufsize);
@ -592,15 +737,18 @@ static struct ext2fs_extattr_entry *
allocate_entry(const char *name, int attrnamespace, uint16_t offs,
uint32_t size, uint32_t hash)
{
size_t name_len;
const char *attr_name;
int name_len;
struct ext2fs_extattr_entry *entry;
name_len = strlen(name);
attr_name = ext2_extattr_name_to_linux(attrnamespace, name);
name_len = strlen(attr_name);
entry = malloc(sizeof(struct ext2fs_extattr_entry) + name_len,
M_TEMP, M_WAITOK);
entry->e_name_len = name_len;
entry->e_name_index = ext2_extattr_index_to_linux(attrnamespace);
entry->e_name_index = ext2_extattr_attrnamespace_to_linux(attrnamespace, name);
entry->e_value_offs = offs;
entry->e_value_block = 0;
entry->e_value_size = size;
@ -727,6 +875,8 @@ ext2_extattr_inode_set(struct inode *ip, int attrnamespace,
struct buf *bp;
struct ext2fs_extattr_dinode_header *header;
struct ext2fs_extattr_entry *entry;
const char *attr_name;
int name_len;
size_t size = 0, max_size;
int error;
@ -762,11 +912,20 @@ ext2_extattr_inode_set(struct inode *ip, int attrnamespace,
/* Find if entry exist */
for (entry = EXT2_IFIRST(header); !EXT2_IS_LAST_ENTRY(entry);
entry = EXT2_EXTATTR_NEXT(entry)) {
if (ext2_extattr_index_to_bsd(entry->e_name_index) != attrnamespace)
if (ext2_extattr_attrnamespace_to_bsd(entry->e_name_index) !=
attrnamespace)
continue;
if (strlen(name) == entry->e_name_len &&
0 == strncmp(entry->e_name, name, entry->e_name_len))
name_len = entry->e_name_len;
attr_name = ext2_extattr_name_to_bsd(entry->e_name_index,
entry->e_name, &name_len);
if (!attr_name) {
brelse(bp);
return (ENOTSUP);
}
if (strlen(name) == name_len &&
0 == strncmp(attr_name, name, name_len))
break;
}
@ -876,6 +1035,8 @@ ext2_extattr_block_set(struct inode *ip, int attrnamespace,
struct buf *bp;
struct ext2fs_extattr_header *header;
struct ext2fs_extattr_entry *entry;
const char *attr_name;
int name_len;
size_t size;
int error;
@ -916,11 +1077,20 @@ ext2_extattr_block_set(struct inode *ip, int attrnamespace,
/* Find if entry exist */
for (entry = EXT2_FIRST_ENTRY(bp); !EXT2_IS_LAST_ENTRY(entry);
entry = EXT2_EXTATTR_NEXT(entry)) {
if (ext2_extattr_index_to_bsd(entry->e_name_index) != attrnamespace)
if (ext2_extattr_attrnamespace_to_bsd(entry->e_name_index) !=
attrnamespace)
continue;
if (strlen(name) == entry->e_name_len &&
0 == strncmp(entry->e_name, name, entry->e_name_len))
name_len = entry->e_name_len;
attr_name = ext2_extattr_name_to_bsd(entry->e_name_index,
entry->e_name, &name_len);
if (!attr_name) {
brelse(bp);
return (ENOTSUP);
}
if (strlen(name) == name_len &&
0 == strncmp(attr_name, name, name_len))
break;
}
@ -961,7 +1131,8 @@ ext2_extattr_block_set(struct inode *ip, int attrnamespace,
}
size = ext2_extattr_get_size(NULL, NULL,
sizeof(struct ext2fs_extattr_header), strlen(name), uio->uio_resid);
sizeof(struct ext2fs_extattr_header),
strlen(ext2_extattr_name_to_linux(attrnamespace, name)), uio->uio_resid);
if (size > fs->e2fs_bsize)
return (ENOSPC);

View File

@ -81,6 +81,7 @@
#include <fs/ext2fs/fs.h>
#include <fs/ext2fs/inode.h>
#include <fs/ext2fs/ext2_acl.h>
#include <fs/ext2fs/ext2_extern.h>
#include <fs/ext2fs/ext2fs.h>
#include <fs/ext2fs/ext2_dinode.h>
@ -163,6 +164,9 @@ struct vop_vector ext2_vnodeops = {
.vop_getextattr = ext2_getextattr,
.vop_listextattr = ext2_listextattr,
.vop_setextattr = ext2_setextattr,
.vop_getacl = ext2_getacl,
.vop_setacl = ext2_setacl,
.vop_aclcheck = ext2_aclcheck,
.vop_vptofh = ext2_vptofh,
};
@ -1083,6 +1087,150 @@ ext2_rename(struct vop_rename_args *ap)
return (error);
}
static int
ext2_do_posix1e_acl_inheritance_dir(struct vnode *dvp, struct vnode *tvp,
mode_t dmode, struct ucred *cred, struct thread *td)
{
int error;
struct inode *ip = VTOI(tvp);
struct acl *dacl, *acl;
acl = acl_alloc(M_WAITOK);
dacl = acl_alloc(M_WAITOK);
/*
* Retrieve default ACL from parent, if any.
*/
error = VOP_GETACL(dvp, ACL_TYPE_DEFAULT, acl, cred, td);
switch (error) {
case 0:
/*
* Retrieved a default ACL, so merge mode and ACL if
* necessary. If the ACL is empty, fall through to
* the "not defined or available" case.
*/
if (acl->acl_cnt != 0) {
dmode = acl_posix1e_newfilemode(dmode, acl);
ip->i_mode = dmode;
*dacl = *acl;
ext2_sync_acl_from_inode(ip, acl);
break;
}
/* FALLTHROUGH */
case EOPNOTSUPP:
/*
* Just use the mode as-is.
*/
ip->i_mode = dmode;
error = 0;
goto out;
default:
goto out;
}
error = VOP_SETACL(tvp, ACL_TYPE_ACCESS, acl, cred, td);
if (error == 0)
error = VOP_SETACL(tvp, ACL_TYPE_DEFAULT, dacl, cred, td);
switch (error) {
case 0:
break;
case EOPNOTSUPP:
/*
* XXX: This should not happen, as EOPNOTSUPP above
* was supposed to free acl.
*/
#ifdef DEBUG
printf("ext2_mkdir: VOP_GETACL() but no VOP_SETACL()\n");
#endif /* DEBUG */
break;
default:
goto out;
}
out:
acl_free(acl);
acl_free(dacl);
return (error);
}
static int
ext2_do_posix1e_acl_inheritance_file(struct vnode *dvp, struct vnode *tvp,
mode_t mode, struct ucred *cred, struct thread *td)
{
int error;
struct inode *ip = VTOI(tvp);
struct acl *acl;
acl = acl_alloc(M_WAITOK);
/*
* Retrieve default ACL for parent, if any.
*/
error = VOP_GETACL(dvp, ACL_TYPE_DEFAULT, acl, cred, td);
switch (error) {
case 0:
/*
* Retrieved a default ACL, so merge mode and ACL if
* necessary.
*/
if (acl->acl_cnt != 0) {
/*
* Two possible ways for default ACL to not
* be present. First, the EA can be
* undefined, or second, the default ACL can
* be blank. If it's blank, fall through to
* the it's not defined case.
*/
mode = acl_posix1e_newfilemode(mode, acl);
ip->i_mode = mode;
ext2_sync_acl_from_inode(ip, acl);
break;
}
/* FALLTHROUGH */
case EOPNOTSUPP:
/*
* Just use the mode as-is.
*/
ip->i_mode = mode;
error = 0;
goto out;
default:
goto out;
}
error = VOP_SETACL(tvp, ACL_TYPE_ACCESS, acl, cred, td);
switch (error) {
case 0:
break;
case EOPNOTSUPP:
/*
* XXX: This should not happen, as EOPNOTSUPP above was
* supposed to free acl.
*/
printf("ufs_do_posix1e_acl_inheritance_file: VOP_GETACL() "
"but no VOP_SETACL()\n");
/* panic("ufs_do_posix1e_acl_inheritance_file: VOP_GETACL() "
"but no VOP_SETACL()"); */
break;
default:
goto out;
}
out:
acl_free(acl);
return (error);
}
/*
* Mkdir system call
*/
@ -1192,6 +1340,13 @@ ext2_mkdir(struct vop_mkdir_args *ap)
ip->i_flag |= IN_CHANGE;
}
if (dvp->v_mount->mnt_flag & MNT_ACLS) {
error = ext2_do_posix1e_acl_inheritance_dir(dvp, tvp, dmode,
cnp->cn_cred, cnp->cn_thread);
if (error)
goto bad;
}
/* Directory set up, now install its entry in the parent directory. */
error = ext2_direnter(ip, dvp, cnp);
if (error) {
@ -1446,6 +1601,18 @@ ext2_pathconf(struct vop_pathconf_args *ap)
case _PC_NO_TRUNC:
*ap->a_retval = 1;
break;
case _PC_ACL_EXTENDED:
if (ap->a_vp->v_mount->mnt_flag & MNT_ACLS)
*ap->a_retval = 1;
else
*ap->a_retval = 0;
break;
case _PC_ACL_PATH_MAX:
if (ap->a_vp->v_mount->mnt_flag & MNT_ACLS)
*ap->a_retval = ACL_MAX_ENTRIES;
else
*ap->a_retval = 3;
break;
case _PC_MIN_HOLE_SIZE:
*ap->a_retval = ap->a_vp->v_mount->mnt_stat.f_iosize;
break;
@ -1513,6 +1680,8 @@ ext2_deleteextattr(struct vop_deleteextattr_args *ap)
if (error)
return (error);
error = ENOATTR;
if (EXT2_INODE_SIZE(fs) != E2FS_REV0_INODE_SIZE) {
error = ext2_extattr_inode_delete(ip, ap->a_attrnamespace, ap->a_name);
if (error != ENOATTR)
@ -1552,6 +1721,8 @@ ext2_getextattr(struct vop_getextattr_args *ap)
if (ap->a_size != NULL)
*ap->a_size = 0;
error = ENOATTR;
if (EXT2_INODE_SIZE(fs) != E2FS_REV0_INODE_SIZE) {
error = ext2_extattr_inode_get(ip, ap->a_attrnamespace,
ap->a_name, ap->a_uio, ap->a_size);
@ -1755,6 +1926,14 @@ ext2_makeinode(int mode, struct vnode *dvp, struct vnode **vpp,
error = ext2_update(tvp, !DOINGASYNC(tvp));
if (error)
goto bad;
if (dvp->v_mount->mnt_flag & MNT_ACLS) {
error = ext2_do_posix1e_acl_inheritance_file(dvp, tvp, mode,
cnp->cn_cred, cnp->cn_thread);
if (error)
goto bad;
}
error = ext2_direnter(ip, dvp, cnp);
if (error)
goto bad;

View File

@ -490,14 +490,13 @@ nfscl_loadattrcache(struct vnode **vpp, struct nfsvattr *nap, void *nvaper,
* from the value used for the top level server volume
* in the mounted subtree.
*/
if (vp->v_mount->mnt_stat.f_fsid.val[0] !=
(uint32_t)np->n_vattr.na_filesid[0])
vap->va_fsid = (uint32_t)np->n_vattr.na_filesid[0];
else
vap->va_fsid = (uint32_t)hash32_buf(
vn_fsid(vp, vap);
vap->va_fsid = np->n_vattr.na_filesid[0];
if (vap->va_fsid == np->n_vattr.na_filesid[0])
vap->va_fsid = hash32_buf(
np->n_vattr.na_filesid, 2 * sizeof(uint64_t), 0);
} else
vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
vn_fsid(vp, vap);
np->n_attrstamp = time_second;
if (vap->va_size != np->n_size) {
if (vap->va_type == VREG) {

View File

@ -359,6 +359,10 @@ soo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
inpcb = (struct inpcb *)(so->so_pcb);
kif->kf_un.kf_sock.kf_sock_inpcb =
(uintptr_t)inpcb->inp_ppcb;
kif->kf_un.kf_sock.kf_sock_sendq =
sbused(&so->so_snd);
kif->kf_un.kf_sock.kf_sock_recvq =
sbused(&so->so_rcv);
}
}
break;
@ -372,6 +376,10 @@ soo_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp)
so->so_rcv.sb_state;
kif->kf_un.kf_sock.kf_sock_snd_sb_state =
so->so_snd.sb_state;
kif->kf_un.kf_sock.kf_sock_sendq =
sbused(&so->so_snd);
kif->kf_un.kf_sock.kf_sock_recvq =
sbused(&so->so_rcv);
}
}
break;

View File

@ -2493,3 +2493,14 @@ vn_mmap(struct file *fp, vm_map_t map, vm_offset_t *addr, vm_size_t size,
#endif
return (error);
}
void
vn_fsid(struct vnode *vp, struct vattr *va)
{
fsid_t *f;
f = &vp->v_mount->mnt_stat.f_fsid;
va->va_fsid = (uint32_t)f->val[1];
va->va_fsid <<= sizeof(f->val[1]) * NBBY;
va->va_fsid += (uint32_t)f->val[0];
}

View File

@ -528,13 +528,14 @@ typedef enum {
#define AR71XX_SPI_RDS 0x0C
#define ATH_READ_REG(reg) \
*((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((reg)))
*((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((reg)))
/*
* Note: Don't put a flush read here; some users (eg the AR724x PCI fixup code)
* requires write-only space to certain registers. Doing the read afterwards
* causes things to break.
*/
#define ATH_WRITE_REG(reg, val) \
do { \
*((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((reg))) = (val); \
(void) ATH_READ_REG(reg); \
} while (0)
*((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((reg))) = (val)
static inline void
ar71xx_ddr_flush(uint32_t reg)

View File

@ -208,7 +208,7 @@ bcm_get_uart_rclk(struct bcm_platform *bp)
uint64_t
bcm_get_alpfreq(struct bcm_platform *bp) {
if (!bcm_has_pmu(bp))
panic("%s requires PMU\n", __FUNCTION__);
return (BHND_PMU_ALP_CLOCK);
return (bhnd_pmu_alp_clock(bcm_get_pmu(bp)));
}
@ -217,7 +217,7 @@ bcm_get_alpfreq(struct bcm_platform *bp) {
uint64_t
bcm_get_ilpfreq(struct bcm_platform *bp) {
if (!bcm_has_pmu(bp))
panic("%s requires PMU\n", __FUNCTION__);
return (BHND_PMU_ILP_CLOCK);
return (bhnd_pmu_ilp_clock(bcm_get_pmu(bp)));
}

View File

@ -15,12 +15,14 @@ hint.argemdio.0.order=0
hint.arge.0.phymask=0x10 # PHY 4
# hint.arge.0.miimode=2 # MII
hint.arge.0.mdio=mdioproxy1 # Hanging off the arswitch MDIO bus
hint.arge.0.eeprommac=0x1fff0000
# arge1: connected to the LAN switch MAC, at 1000BaseTX / GMII.
hint.arge.1.phymask=0x0
# hint.arge.1.miimode=1 # GMII
hint.arge.1.media=1000 # Force to 1000BaseTX/full
hint.arge.1.fduplex=1
hint.arge.1.eeprommac=0x1fff0006
#
# AR7240 switch config
@ -94,29 +96,15 @@ hint.map.1.readonly=1
hint.map.2.at="flash/spi0"
hint.map.2.start=0x00080000
# hint.map.2.end=0x00380000
hint.map.2.end=0x00780000
# hint.map.2.name="spare-rootfs"
hint.map.2.name="rootfs"
hint.map.2.readonly=1
#hint.map.3.at="flash/spi0"
#hint.map.3.start=0x00380000
#hint.map.3.end=0x00480000
#hint.map.3.name="spare-uImage"
#hint.map.3.readonly=1
#hint.map.4.at="flash/spi0"
#hint.map.4.start=0x00480000
#hint.map.4.end=0x00780000
#hint.map.4.name="rootfs"
#hint.map.4.readonly=1
hint.map.2.end="search:0x00080000:0x10000:.!/bin/sh"
hint.map.2.name="kernel"
hint.map.2.readonly=0
hint.map.3.at="flash/spi0"
hint.map.3.start=0x00780000
hint.map.3.start="search:0x00080000:0x10000:.!/bin/sh"
hint.map.3.end=0x00880000
hint.map.3.name="uImage"
hint.map.3.readonly=1
hint.map.3.name="rootfs"
hint.map.3.readonly=0
hint.map.4.at="flash/spi0"
hint.map.4.start=0x00880000

View File

@ -25,13 +25,14 @@ makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
# Build these as modules so small platform builds will have the
# modules already built.
makeoptions MODULES_OVERRIDE="gpio ar71xx if_gif if_gre if_bridge bridgestp usb wlan wlan_xauth wlan_acl wlan_wep wlan_tkip wlan_ccmp wlan_rssadapt wlan_amrr ath ath_pci hwpmc cam"
makeoptions MODULES_OVERRIDE="gpio ar71xx if_gif if_gre if_tap if_tun libalias ipfw ipfw_nat ipfw_nptv6 if_vlan if_bridge bridgestp usb wlan wlan_xauth wlan_acl wlan_wep wlan_tkip wlan_ccmp wlan_rssadapt wlan_amrr ath_main ath_pci ath_hal ath_hal_ar5212 ath_hal_ar5416 ath_hal_ar9300 ath_rate ath_dfs hwpmc hwpmc_mips24k cam"
# For small memory footprints
options VM_KMEM_SIZE_SCALE=1
options DDB
options KDB
options EARLY_PRINTF
options SCHED_4BSD #4BSD scheduler
options INET #InterNETworking
@ -59,11 +60,16 @@ options NO_SYSCTL_DESCR
options FFS #Berkeley Fast Filesystem
options NO_FFS_SNAPSHOT
options IPFIREWALL_DEFAULT_TO_ACCEPT
# options SOFTUPDATES #Enable FFS soft updates support
# options UFS_ACL #Support for access control lists
# options UFS_DIRHASH #Improve performance on big directories
# options MSDOSFS # Read MSDOS filesystems; useful for USB/CF
options UMTX_CHAINS=16
device pci
device ar724x_pci
@ -129,7 +135,7 @@ device loop
device ether
device md
device bpf
#device random
device random
#device if_bridge
#device gif # ip[46] in ip[46] tunneling protocol
#device gre # generic encapsulation - only for IPv4 in IPv4 though atm

View File

@ -3,8 +3,8 @@
.PATH: ${SRCTOP}/sys/fs/ext2fs
KMOD= ext2fs
SRCS= opt_ddb.h opt_directio.h opt_quota.h opt_suiddir.h vnode_if.h \
ext2_alloc.c ext2_balloc.c ext2_bmap.c ext2_extattr.c ext2_extents.c \
ext2_hash.c ext2_htree.c ext2_inode.c ext2_inode_cnv.c ext2_lookup.c \
ext2_subr.c ext2_vfsops.c ext2_vnops.c
ext2_acl.c ext2_alloc.c ext2_balloc.c ext2_bmap.c ext2_extattr.c \
ext2_extents.c ext2_hash.c ext2_htree.c ext2_inode.c ext2_inode_cnv.c \
ext2_lookup.c ext2_subr.c ext2_vfsops.c ext2_vnops.c
.include <bsd.kmod.mk>

View File

@ -15,7 +15,7 @@ SRCS= linux_fork.c linux${SFX}_dummy.c linux_file.c linux_event.c \
linux${SFX}_machdep.c linux_misc.c linux_signal.c \
linux_socket.c linux_stats.c linux_sysctl.c linux${SFX}_sysent.c \
linux${SFX}_sysvec.c linux_uid16.c linux_time.c \
linux_timer.c linux_vdso.c \
linux_timer.c linux_vdso.c opt_global.h \
opt_inet6.h opt_compat.h opt_posix.h opt_usb.h vnode_if.h \
device_if.h bus_if.h assym.s \
linux${SFX}_support.s
@ -64,10 +64,12 @@ linux${SFX}_support.o: linux${SFX}_assym.h assym.s
${VDSO}.so: linux${SFX}_locore.o
${OBJCOPY} --input-target binary --output-target elf64-x86-64-freebsd \
--binary-architecture i386 linux${SFX}_locore.o ${.TARGET}
strip -N _binary_linux${SFX}_locore_o_size ${.TARGET}
.else
${VDSO}.so: linux${SFX}_locore.o
${OBJCOPY} --input-target binary --output-target elf32-i386-freebsd \
--binary-architecture i386 linux${SFX}_locore.o ${.TARGET}
strip -N _binary_linux_locore_o_size ${.TARGET}
.endif
linux${SFX}_genassym.o:

View File

@ -10,7 +10,7 @@ SRCS= linux_fork.c linux_dummy.c linux_file.c linux_event.c \
linux_machdep.c linux_misc.c linux_ptrace.c linux_signal.c \
linux_socket.c linux_stats.c linux_sysctl.c linux_sysent.c \
linux_sysvec.c linux_time.c linux_vdso.c linux_timer.c \
opt_inet6.h opt_compat.h opt_posix.h opt_usb.h \
opt_inet6.h opt_compat.h opt_global.h opt_posix.h opt_usb.h \
vnode_if.h device_if.h bus_if.h assym.s \
linux_support.s
DPSRCS= linux_genassym.c
@ -38,6 +38,7 @@ linux_locore.o: linux_locore.s linux_assym.h
${VDSO}.so: linux_locore.o
${OBJCOPY} --input-target binary --output-target elf64-x86-64-freebsd \
-S -g --binary-architecture i386:x86-64 linux_locore.o ${.TARGET}
strip -N _binary_linux_locore_o_size ${.TARGET}
linux_support.o: assym.s linux_assym.h
${CC} -c -x assembler-with-cpp -DLOCORE ${CFLAGS} \

View File

@ -572,24 +572,41 @@ static void
lagg_capabilities(struct lagg_softc *sc)
{
struct lagg_port *lp;
int cap = ~0, ena = ~0;
u_long hwa = ~0UL;
int cap, ena, pena;
uint64_t hwa;
struct ifnet_hw_tsomax hw_tsomax;
LAGG_XLOCK_ASSERT(sc);
memset(&hw_tsomax, 0, sizeof(hw_tsomax));
/* Get common enabled capabilities for the lagg ports */
ena = ~0;
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
ena &= lp->lp_ifp->if_capenable;
ena = (ena == ~0 ? 0 : ena);
/* Get capabilities from the lagg ports */
/*
* Apply common enabled capabilities back to the lagg ports.
* May require several iterations if they are dependent.
*/
do {
pena = ena;
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
lagg_setcaps(lp, ena);
ena &= lp->lp_ifp->if_capenable;
}
} while (pena != ena);
/* Get other capabilities from the lagg ports */
cap = ~0;
hwa = ~(uint64_t)0;
memset(&hw_tsomax, 0, sizeof(hw_tsomax));
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) {
cap &= lp->lp_ifp->if_capabilities;
ena &= lp->lp_ifp->if_capenable;
hwa &= lp->lp_ifp->if_hwassist;
if_hw_tsomax_common(lp->lp_ifp, &hw_tsomax);
}
cap = (cap == ~0 ? 0 : cap);
ena = (ena == ~0 ? 0 : ena);
hwa = (hwa == ~0 ? 0 : hwa);
hwa = (hwa == ~(uint64_t)0 ? 0 : hwa);
if (sc->sc_ifp->if_capabilities != cap ||
sc->sc_ifp->if_capenable != ena ||
@ -604,10 +621,6 @@ lagg_capabilities(struct lagg_softc *sc)
if_printf(sc->sc_ifp,
"capabilities 0x%08x enabled 0x%08x\n", cap, ena);
}
/* Apply unified capabilities back to the lagg ports. */
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries)
lagg_setcaps(lp, ena);
}
static int
@ -888,6 +901,7 @@ lagg_port_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
LAGG_XLOCK(sc);
lagg_capabilities(sc);
LAGG_XUNLOCK(sc);
VLAN_CAPABILITIES(sc->sc_ifp);
break;
case SIOCSIFMTU:
@ -1001,6 +1015,7 @@ lagg_port_ifdetach(void *arg __unused, struct ifnet *ifp)
lp->lp_detaching = 1;
lagg_port_destroy(lp, 1);
LAGG_XUNLOCK(sc);
VLAN_CAPABILITIES(sc->sc_ifp);
}
static void
@ -1360,6 +1375,7 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
error = lagg_port_create(sc, tpif);
LAGG_XUNLOCK(sc);
if_rele(tpif);
VLAN_CAPABILITIES(ifp);
break;
case SIOCSLAGGDELPORT:
error = priv_check(td, PRIV_NET_LAGG);
@ -1383,6 +1399,7 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
error = lagg_port_destroy(lp, 1);
LAGG_XUNLOCK(sc);
if_rele(tpif);
VLAN_CAPABILITIES(ifp);
break;
case SIOCSIFFLAGS:
/* Set flags on ports too */
@ -1433,6 +1450,7 @@ lagg_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
}
lagg_capabilities(sc);
LAGG_XUNLOCK(sc);
VLAN_CAPABILITIES(ifp);
error = 0;
break;

View File

@ -299,7 +299,13 @@ VNET_DECLARE(int, natt_cksum_policy);
#define ipseclog(x) do { if (V_ipsec_debug) log x; } while (0)
/* for openbsd compatibility */
#ifdef IPSEC_DEBUG
#define IPSEC_DEBUG_DECLARE(x) x
#define DPRINTF(x) do { if (V_ipsec_debug) printf x; } while (0)
#else
#define IPSEC_DEBUG_DECLARE(x)
#define DPRINTF(x)
#endif
struct inpcb;
struct m_tag;

View File

@ -117,7 +117,7 @@ __FBSDID("$FreeBSD$");
static int
ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto)
{
char buf[IPSEC_ADDRSTRLEN];
IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]);
union sockaddr_union dst_address;
struct secasvar *sav;
uint32_t spi;
@ -277,7 +277,7 @@ int
ipsec4_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip,
int protoff)
{
char buf[IPSEC_ADDRSTRLEN];
IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]);
struct ipsec_ctx_data ctx;
struct xform_history *xh;
struct secasindex *saidx;
@ -488,7 +488,7 @@ int
ipsec6_common_input_cb(struct mbuf *m, struct secasvar *sav, int skip,
int protoff)
{
char buf[IPSEC_ADDRSTRLEN];
IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]);
struct ipsec_ctx_data ctx;
struct xform_history *xh;
struct secasindex *saidx;

View File

@ -183,7 +183,6 @@ ipsec4_allocsa(struct mbuf *m, struct secpolicy *sp, u_int *pidx, int *error)
static int
ipsec4_perform_request(struct mbuf *m, struct secpolicy *sp, u_int idx)
{
char sbuf[IPSEC_ADDRSTRLEN], dbuf[IPSEC_ADDRSTRLEN];
struct ipsec_ctx_data ctx;
union sockaddr_union *dst;
struct secasvar *sav;
@ -230,12 +229,9 @@ ipsec4_perform_request(struct mbuf *m, struct secpolicy *sp, u_int idx)
ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
error = ipsec_encap(&m, &sav->sah->saidx);
if (error != 0) {
DPRINTF(("%s: encapsulation for SA %s->%s "
"SPI 0x%08x failed with error %d\n", __func__,
ipsec_address(&sav->sah->saidx.src, sbuf,
sizeof(sbuf)),
ipsec_address(&sav->sah->saidx.dst, dbuf,
sizeof(dbuf)), ntohl(sav->spi), error));
DPRINTF(("%s: encapsulation for SPI 0x%08x failed "
"with error %d\n", __func__, ntohl(sav->spi),
error));
/* XXXAE: IPSEC_OSTAT_INC(tunnel); */
goto bad;
}
@ -497,7 +493,6 @@ ipsec6_allocsa(struct mbuf *m, struct secpolicy *sp, u_int *pidx, int *error)
static int
ipsec6_perform_request(struct mbuf *m, struct secpolicy *sp, u_int idx)
{
char sbuf[IPSEC_ADDRSTRLEN], dbuf[IPSEC_ADDRSTRLEN];
struct ipsec_ctx_data ctx;
union sockaddr_union *dst;
struct secasvar *sav;
@ -539,12 +534,9 @@ ipsec6_perform_request(struct mbuf *m, struct secpolicy *sp, u_int idx)
}
error = ipsec_encap(&m, &sav->sah->saidx);
if (error != 0) {
DPRINTF(("%s: encapsulation for SA %s->%s "
"SPI 0x%08x failed with error %d\n", __func__,
ipsec_address(&sav->sah->saidx.src, sbuf,
sizeof(sbuf)),
ipsec_address(&sav->sah->saidx.dst, dbuf,
sizeof(dbuf)), ntohl(sav->spi), error));
DPRINTF(("%s: encapsulation for SPI 0x%08x failed "
"with error %d\n", __func__, ntohl(sav->spi),
error));
/* XXXAE: IPSEC_OSTAT_INC(tunnel); */
goto bad;
}

View File

@ -53,10 +53,14 @@
#define KEYDEBUG_IPSEC_DATA (KEYDEBUG_IPSEC | KEYDEBUG_DATA)
#define KEYDEBUG_IPSEC_DUMP (KEYDEBUG_IPSEC | KEYDEBUG_DUMP)
#ifdef IPSEC_DEBUG
#define KEYDBG(lev, arg) \
if ((V_key_debug_level & (KEYDEBUG_ ## lev)) == (KEYDEBUG_ ## lev)) { \
arg; \
}
#else
#define KEYDBG(lev, arg)
#endif /* !IPSEC_DEBUG */
VNET_DECLARE(uint32_t, key_debug_level);
#define V_key_debug_level VNET(key_debug_level)

View File

@ -544,7 +544,7 @@ ah_massage_headers(struct mbuf **m0, int proto, int skip, int alg, int out)
static int
ah_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
{
char buf[128];
IPSEC_DEBUG_DECLARE(char buf[128]);
const struct auth_hash *ahx;
struct cryptodesc *crda;
struct cryptop *crp;
@ -681,7 +681,7 @@ ah_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
static int
ah_input_cb(struct cryptop *crp)
{
char buf[IPSEC_ADDRSTRLEN];
IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]);
unsigned char calc[AH_ALEN_MAX];
const struct auth_hash *ahx;
struct mbuf *m;
@ -831,7 +831,7 @@ static int
ah_output(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav,
u_int idx, int skip, int protoff)
{
char buf[IPSEC_ADDRSTRLEN];
IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]);
const struct auth_hash *ahx;
struct cryptodesc *crda;
struct xform_data *xd;

View File

@ -263,7 +263,7 @@ esp_zeroize(struct secasvar *sav)
static int
esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
{
char buf[128];
IPSEC_DEBUG_DECLARE(char buf[128]);
const struct auth_hash *esph;
const struct enc_xform *espx;
struct xform_data *xd;
@ -436,7 +436,7 @@ esp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
static int
esp_input_cb(struct cryptop *crp)
{
char buf[128];
IPSEC_DEBUG_DECLARE(char buf[128]);
u_int8_t lastthree[3], aalg[AH_HMAC_MAXHASHLEN];
const struct auth_hash *esph;
const struct enc_xform *espx;
@ -622,7 +622,7 @@ static int
esp_output(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav,
u_int idx, int skip, int protoff)
{
char buf[IPSEC_ADDRSTRLEN];
IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]);
struct cryptodesc *crde = NULL, *crda = NULL;
struct cryptop *crp;
const struct auth_hash *esph;

View File

@ -271,7 +271,7 @@ ipcomp_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
static int
ipcomp_input_cb(struct cryptop *crp)
{
char buf[IPSEC_ADDRSTRLEN];
IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]);
struct cryptodesc *crd;
struct xform_data *xd;
struct mbuf *m;
@ -387,7 +387,7 @@ static int
ipcomp_output(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav,
u_int idx, int skip, int protoff)
{
char buf[IPSEC_ADDRSTRLEN];
IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]);
const struct comp_algo *ipcompx;
struct cryptodesc *crdc;
struct cryptop *crp;
@ -521,7 +521,7 @@ ipcomp_output(struct mbuf *m, struct secpolicy *sp, struct secasvar *sav,
static int
ipcomp_output_cb(struct cryptop *crp)
{
char buf[IPSEC_ADDRSTRLEN];
IPSEC_DEBUG_DECLARE(char buf[IPSEC_ADDRSTRLEN]);
struct xform_data *xd;
struct secpolicy *sp;
struct secasvar *sav;

View File

@ -344,7 +344,8 @@ struct kinfo_file {
int64_t kf_offset; /* Seek location. */
union {
struct {
uint32_t kf_spareint;
/* Sendq size */
uint32_t kf_sock_sendq;
/* Socket domain. */
int kf_sock_domain0;
/* Socket type. */
@ -365,8 +366,8 @@ struct kinfo_file {
uint16_t kf_sock_snd_sb_state;
/* Receive buffer state. */
uint16_t kf_sock_rcv_sb_state;
/* Round to 64 bit alignment. */
uint32_t kf_sock_pad0;
/* Recvq size. */
uint32_t kf_sock_recvq;
} kf_sock;
struct {
/* Vnode type. */

View File

@ -885,6 +885,8 @@ int vn_chmod(struct file *fp, mode_t mode, struct ucred *active_cred,
int vn_chown(struct file *fp, uid_t uid, gid_t gid, struct ucred *active_cred,
struct thread *td);
void vn_fsid(struct vnode *vp, struct vattr *va);
#endif /* _KERNEL */
#endif /* !_SYS_VNODE_H_ */

View File

@ -381,18 +381,14 @@ struct pagerops swappagerops = {
};
/*
* dmmax is in page-sized chunks with the new swap system. It was
* dev-bsized chunks in the old. dmmax is always a power of 2.
*
* swap_*() routines are externally accessible. swp_*() routines are
* internal.
*/
static int dmmax;
static int nswap_lowat = 128; /* in pages, swap_pager_almost_full warn */
static int nswap_hiwat = 512; /* in pages, swap_pager_almost_full warn */
SYSCTL_INT(_vm, OID_AUTO, dmmax, CTLFLAG_RD, &dmmax, 0,
"Maximum size of a swap block");
SYSCTL_INT(_vm, OID_AUTO, dmmax, CTLFLAG_RD, &nsw_cluster_max, 0,
"Maximum size of a swap block in pages");
static void swp_sizecheck(void);
static void swp_pager_async_iodone(struct buf *bp);
@ -489,11 +485,6 @@ swap_pager_init(void)
mtx_init(&sw_dev_mtx, "swapdev", NULL, MTX_DEF);
sx_init(&sw_alloc_sx, "swspsx");
sx_init(&swdev_syscall_lock, "swsysc");
/*
* Device Stripe, in PAGE_SIZE'd blocks
*/
dmmax = SWB_NPAGES * 2;
}
/*
@ -2310,9 +2301,13 @@ swapoff_one(struct swdevt *sp, struct ucred *cred)
*/
mtx_lock(&sw_dev_mtx);
sp->sw_flags |= SW_CLOSING;
for (dvbase = 0; dvbase < sp->sw_end; dvbase += dmmax) {
for (dvbase = 0; dvbase < nblks; dvbase += BLIST_BMAP_RADIX) {
/*
* blist_fill() cannot allocate more than BLIST_BMAP_RADIX
* blocks per call.
*/
swap_pager_avail -= blist_fill(sp->sw_blist,
dvbase, dmmax);
dvbase, ulmin(nblks - dvbase, BLIST_BMAP_RADIX));
}
swap_total -= (vm_ooffset_t)nblks * PAGE_SIZE;
mtx_unlock(&sw_dev_mtx);

View File

@ -60,14 +60,14 @@ int
main(void)
{
int error, fd, fds[2], i, read_only_fd;
char path[PATH_MAX];
char path[] = "ftruncate_file";
struct stat sb;
ssize_t size;
off_t len;
char ch;
/*
* Tests using a writable temporary file: grow and then shrink a file
* Tests using a writable file: grow and then shrink a file
* using ftruncate and various lengths. Make sure that a negative
* file length is rejected. Make sure that when we grow the file,
* bytes now in the range of the file size return 0.
@ -75,37 +75,36 @@ main(void)
* Save a read-only reference to the file to use later for read-only
* descriptor tests.
*/
snprintf(path, PATH_MAX, "/tmp/ftruncate.XXXXXXXXXXXXX");
fd = mkstemp(path);
fd = open(path, O_RDWR|O_CREAT, 0600);
if (fd < 0)
err(-1, "mkstemp");
err(1, "open(%s, O_RDWR|O_CREAT, 0600)", path);
read_only_fd = open(path, O_RDONLY);
if (read_only_fd < 0) {
error = errno;
(void)unlink(path);
errno = error;
err(-1, "open(%s, O_RDONLY)", path);
err(1, "open(%s, O_RDONLY)", path);
}
(void)unlink(path);
if (ftruncate(fd, -1) == 0)
errx(-1, "ftruncate(fd, -1) succeeded");
errx(1, "ftruncate(fd, -1) succeeded unexpectedly");
if (errno != EINVAL)
err(-1, "ftruncate(fd, -1) returned wrong error");
err(1, "ftruncate(fd, -1) returned wrong error");
for (i = 0; i < lengths_count; i++) {
len = lengths[i];
if (ftruncate(fd, len) < 0)
err(-1, "ftruncate(%jd) up", (intmax_t)len);
err(1, "ftruncate(%jd) up", (intmax_t)len);
if (fstat(fd, &sb) < 0)
err(-1, "stat");
err(1, "stat");
if (sb.st_size != len)
errx(-1, "fstat with len=%jd returned len %jd up",
(intmax_t)len, (intmax_t)sb.st_size);
if (len != 0) {
size = pread(fd, &ch, sizeof(ch), len - 1);
if (size < 0)
err(-1, "pread on len %jd up", (intmax_t)len);
err(1, "pread on len %jd up", (intmax_t)len);
if (size != sizeof(ch))
errx(-1, "pread len %jd size %jd up",
(intmax_t)len, (intmax_t)size);
@ -119,9 +118,9 @@ main(void)
for (i = lengths_count - 1; i >= 0; i--) {
len = lengths[i];
if (ftruncate(fd, len) < 0)
err(-1, "ftruncate(%jd) down", (intmax_t)len);
err(1, "ftruncate(%jd) down", (intmax_t)len);
if (fstat(fd, &sb) < 0)
err(-1, "stat");
err(1, "stat");
if (sb.st_size != len)
errx(-1, "fstat(%jd) returned %jd down", (intmax_t)len,
sb.st_size);
@ -134,7 +133,7 @@ main(void)
if (ftruncate(read_only_fd, 0) == 0)
errx(-1, "ftruncate(read_only_fd) succeeded");
if (errno != EINVAL)
err(-1, "ftruncate(read_only_fd) returned wrong error");
err(1, "ftruncate(read_only_fd) returned wrong error");
close(read_only_fd);
/*
@ -142,22 +141,22 @@ main(void)
*/
fd = socket(PF_UNIX, SOCK_STREAM, 0);
if (fd < 0)
err(-1, "socket(PF_UNIX, SOCK_STREAM, 0)");
err(1, "socket(PF_UNIX, SOCK_STREAM, 0)");
if (ftruncate(fd, 0) == 0)
errx(-1, "ftruncate(socket) succeeded");
if (errno != EINVAL)
err(-1, "ftruncate(socket) returned wrong error");
err(1, "ftruncate(socket) returned wrong error");
close(fd);
/*
* Make sure that ftruncate on pipes doesn't work.
*/
if (pipe(fds) < 0)
err(-1, "pipe");
err(1, "pipe");
if (ftruncate(fds[0], 0) == 0)
errx(-1, "ftruncate(pipe) succeeded");
if (errno != EINVAL)
err(-1, "ftruncate(pipe) returned wrong error");
err(1, "ftruncate(pipe) returned wrong error");
close(fds[0]);
close(fds[1]);
@ -166,11 +165,11 @@ main(void)
*/
fd = kqueue();
if (fd < 0)
err(-1, "kqueue");
err(1, "kqueue");
if (ftruncate(fds[0], 0) == 0)
errx(-1, "ftruncate(kqueue) succeeded");
if (errno != EINVAL)
err(-1, "ftruncate(kqueue) returned wrong error");
err(1, "ftruncate(kqueue) returned wrong error");
close(fd);
return (0);

View File

@ -61,8 +61,9 @@ do_accept(__unused void *arg)
accept_fd = accept(listen_fd, NULL, NULL);
if (accept_fd < 0)
err(-1, "accept");
err(1, "accept");
close(accept_fd);
return (NULL);
}
@ -73,7 +74,7 @@ do_fork(void)
pid = fork();
if (pid < 0)
err(-1, "fork");
err(1, "fork");
if (pid > 0) {
waitpid(pid, NULL, 0);
exit(0);
@ -84,37 +85,37 @@ do_fork(void)
* listen_fd+1, and get back EBADF if it's not a valid descriptor,
* and EINVAL if it is. This (currently) works fine in practice.
*/
if (ftruncate(listen_fd + 1, 0 < 0)) {
if (ftruncate(listen_fd + 1, 0) < 0) {
if (errno == EBADF)
exit(0);
else if (errno == EINVAL)
errx(-1, "file descriptor still open in child");
errx(1, "file descriptor still open in child");
else
err(-1, "unexpected error");
err(1, "unexpected error");
} else
errx(-1, "ftruncate succeeded");
errx(1, "ftruncate succeeded");
}
int
main(__unused int argc, __unused char *argv[])
main(void)
{
struct sockaddr_in sin;
pthread_t accept_thread;
listen_fd = socket(PF_INET, SOCK_STREAM, 0);
if (listen_fd < 0)
err(-1, "socket");
err(1, "socket");
bzero(&sin, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_len = sizeof(sin);
sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
sin.sin_port = htons(PORT);
if (bind(listen_fd, (struct sockaddr *)&sin, sizeof(sin)) < 0)
err(-1, "bind");
err(1, "bind");
if (listen(listen_fd, -1) <0)
err(-1, "listen");
err(1, "listen");
if (pthread_create(&accept_thread, NULL, do_accept, NULL) != 0)
err(-1, "pthread_create");
err(1, "pthread_create");
sleep(1); /* Easier than using a CV. */
do_fork();
exit(0);

Some files were not shown because too many files have changed in this diff Show More