summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarkm <markm@FreeBSD.org>2013-08-22 07:10:18 +0000
committermarkm <markm@FreeBSD.org>2013-08-22 07:10:18 +0000
commitebd919f034b5492d5d2693c8cf79e707b25a52bb (patch)
treeb222b60217e3a7914757435440ba08b44e4f9ce9
parent8c10ae99f831cad18194c571d5e44e22bb1001cd (diff)
downloadFreeBSD-src-ebd919f034b5492d5d2693c8cf79e707b25a52bb.zip
FreeBSD-src-ebd919f034b5492d5d2693c8cf79e707b25a52bb.tar.gz
IFC.
-rw-r--r--UPDATING9
-rw-r--r--bin/chflags/chflags.122
-rw-r--r--bin/ls/ls.13
-rw-r--r--lib/libc/gen/strtofflags.c20
-rw-r--r--lib/libc/sys/chflags.266
-rw-r--r--lib/libutil/expand_number.c7
-rw-r--r--share/man/man9/atomic.983
-rw-r--r--sys/amd64/conf/GENERIC4
-rw-r--r--sys/amd64/conf/NOTES2
-rw-r--r--sys/amd64/include/atomic.h97
-rw-r--r--sys/amd64/include/pmap.h43
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c48
-rw-r--r--sys/cddl/dev/dtrace/powerpc/dtrace_asm.S8
-rw-r--r--sys/conf/options.amd644
-rw-r--r--sys/conf/options.i3864
-rw-r--r--sys/dev/hwpmc/pmc_events.h4
-rw-r--r--sys/dev/mps/mps_sas.c4
-rw-r--r--sys/fs/msdosfs/msdosfs_denode.c4
-rw-r--r--sys/fs/msdosfs/msdosfs_vnops.c101
-rw-r--r--sys/fs/smbfs/smbfs_node.c15
-rw-r--r--sys/fs/smbfs/smbfs_vnops.c65
-rw-r--r--sys/i386/conf/GENERIC4
-rw-r--r--sys/i386/conf/NOTES2
-rw-r--r--sys/i386/i386/machdep.c17
-rw-r--r--sys/i386/include/atomic.h383
-rw-r--r--sys/i386/include/pmap.h97
-rw-r--r--sys/net80211/ieee80211_freebsd.h21
-rw-r--r--sys/net80211/ieee80211_hostap.c4
-rw-r--r--sys/net80211/ieee80211_input.c2
-rw-r--r--sys/netinet/in_mcast.c2
-rw-r--r--sys/netinet6/in6_mcast.c2
-rw-r--r--sys/powerpc/conf/GENERIC643
-rw-r--r--sys/sys/param.h2
-rw-r--r--sys/sys/stat.h22
-rw-r--r--sys/ufs/ufs/ufs_vnops.c8
-rw-r--r--sys/vm/vm_pageout.c33
36 files changed, 798 insertions, 417 deletions
diff --git a/UPDATING b/UPDATING
index 86d140d..c0f23b4 100644
--- a/UPDATING
+++ b/UPDATING
@@ -31,6 +31,11 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 10.x IS SLOW:
disable the most expensive debugging functionality run
"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
+20130821:
+ The PADLOCK_RNG and RDRAND_RNG kernel options are now devices.
+ Thus "device padlock_rng" and "device rdrand_rng" should be
+ used instead of "options PADLOCK_RNG" & "options RDRAND_RNG".
+
20130813:
WITH_ICONV has been split into two feature sets. WITH_ICONV now
enables just the iconv* functionality and is now on by default.
@@ -340,9 +345,9 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 10.x IS SLOW:
20120913:
The random(4) support for the VIA hardware random number
generator (`PADLOCK') is no longer enabled unconditionally.
- Add the PADLOCK_RNG option in the custom kernel config if
+ Add the padlock_rng device in the custom kernel config if
needed. The GENERIC kernels on i386 and amd64 do include the
- option, so the change only affects the custom kernel
+ device, so the change only affects the custom kernel
configurations.
20120908:
diff --git a/bin/chflags/chflags.1 b/bin/chflags/chflags.1
index fe9d700..47d5b18 100644
--- a/bin/chflags/chflags.1
+++ b/bin/chflags/chflags.1
@@ -32,7 +32,7 @@
.\" @(#)chflags.1 8.4 (Berkeley) 5/2/95
.\" $FreeBSD$
.\"
-.Dd March 3, 2006
+.Dd April 8, 2013
.Dt CHFLAGS 1
.Os
.Sh NAME
@@ -101,20 +101,36 @@ The following keywords are currently defined:
.Bl -tag -offset indent -width ".Cm opaque"
.It Cm arch , archived
set the archived flag (super-user only)
-.It Cm opaque
-set the opaque flag (owner or super-user only)
.It Cm nodump
set the nodump flag (owner or super-user only)
+.It Cm opaque
+set the opaque flag (owner or super-user only)
.It Cm sappnd , sappend
set the system append-only flag (super-user only)
.It Cm schg , schange , simmutable
set the system immutable flag (super-user only)
+.It Cm snapshot
+set the snapshot flag (filesystems do not allow changing this flag)
.It Cm sunlnk , sunlink
set the system undeletable flag (super-user only)
.It Cm uappnd , uappend
set the user append-only flag (owner or super-user only)
+.It Cm uarch , uarchive
+set the archive flag (owner or super-user only)
.It Cm uchg , uchange , uimmutable
set the user immutable flag (owner or super-user only)
+.It Cm uhidden , hidden
+set the hidden file attribute (owner or super-user only)
+.It Cm uoffline , offline
+set the offline file attribute (owner or super-user only)
+.It Cm urdonly , rdonly , readonly
+set the DOS, Windows and CIFS readonly flag (owner or super-user only)
+.It Cm usparse , sparse
+set the sparse file attribute (owner or super-user only)
+.It Cm usystem , system
+set the DOS, Windows and CIFS system flag (owner or super-user only)
+.It Cm ureparse , reparse
+set the Windows reparse point file attribute (owner or super-user only)
.It Cm uunlnk , uunlink
set the user undeletable flag (owner or super-user only)
.El
diff --git a/bin/ls/ls.1 b/bin/ls/ls.1
index 7c72652..8b7672b 100644
--- a/bin/ls/ls.1
+++ b/bin/ls/ls.1
@@ -232,6 +232,9 @@ output.
Include the file flags in a long
.Pq Fl l
output.
+See
+.Xr chflags 1
+for a list of file flags and their meanings.
.It Fl p
Write a slash
.Pq Ql /
diff --git a/lib/libc/gen/strtofflags.c b/lib/libc/gen/strtofflags.c
index 1edaa5a..55e9945 100644
--- a/lib/libc/gen/strtofflags.c
+++ b/lib/libc/gen/strtofflags.c
@@ -62,13 +62,29 @@ static struct {
#endif
{ "nouappnd", 0, UF_APPEND },
{ "nouappend", 0, UF_APPEND },
+ { "nouarch", 0, UF_ARCHIVE },
+ { "nouarchive", 0, UF_ARCHIVE },
+ { "nohidden", 0, UF_HIDDEN },
+ { "nouhidden", 0, UF_HIDDEN },
{ "nouchg", 0, UF_IMMUTABLE },
{ "nouchange", 0, UF_IMMUTABLE },
{ "nouimmutable", 0, UF_IMMUTABLE },
{ "nodump", 1, UF_NODUMP },
- { "noopaque", 0, UF_OPAQUE },
{ "nouunlnk", 0, UF_NOUNLINK },
- { "nouunlink", 0, UF_NOUNLINK }
+ { "nouunlink", 0, UF_NOUNLINK },
+ { "nooffline", 0, UF_OFFLINE },
+ { "nouoffline", 0, UF_OFFLINE },
+ { "noopaque", 0, UF_OPAQUE },
+ { "nordonly", 0, UF_READONLY },
+ { "nourdonly", 0, UF_READONLY },
+ { "noreadonly", 0, UF_READONLY },
+ { "noureadonly", 0, UF_READONLY },
+ { "noreparse", 0, UF_REPARSE },
+ { "noureparse", 0, UF_REPARSE },
+ { "nosparse", 0, UF_SPARSE },
+ { "nousparse", 0, UF_SPARSE },
+ { "nosystem", 0, UF_SYSTEM },
+ { "nousystem", 0, UF_SYSTEM }
};
#define nmappings (sizeof(mapping) / sizeof(mapping[0]))
diff --git a/lib/libc/sys/chflags.2 b/lib/libc/sys/chflags.2
index 5bc2ba2..9cca54f 100644
--- a/lib/libc/sys/chflags.2
+++ b/lib/libc/sys/chflags.2
@@ -112,26 +112,61 @@ The flags specified are formed by
the following values
.Pp
.Bl -tag -width ".Dv SF_IMMUTABLE" -compact -offset indent
-.It Dv UF_NODUMP
-Do not dump the file.
-.It Dv UF_IMMUTABLE
-The file may not be changed.
-.It Dv UF_APPEND
+.It Dv SF_APPEND
The file may only be appended to.
-.It Dv UF_NOUNLINK
-The file may not be renamed or deleted.
-.It Dv UF_OPAQUE
-The directory is opaque when viewed through a union stack.
.It Dv SF_ARCHIVED
-The file may be archived.
+The file has been archived.
+This flag means the opposite of the DOS, Windows and CIFS
+FILE_ATTRIBUTE_ARCHIVE attribute.
+This flag has been deprecated, and may be removed in a future release.
.It Dv SF_IMMUTABLE
The file may not be changed.
-.It Dv SF_APPEND
-The file may only be appended to.
.It Dv SF_NOUNLINK
The file may not be renamed or deleted.
.It Dv SF_SNAPSHOT
The file is a snapshot file.
+.It Dv UF_APPEND
+The file may only be appended to.
+.It Dv UF_ARCHIVE
+The file needs to be archived.
+This flag has the same meaning as the DOS, Windows and CIFS
+FILE_ATTRIBUTE_ARCHIVE attribute.
+Filesystems in FreeBSD may or may not have special handling for this flag.
+For instance, ZFS tracks changes to files and will set this bit when a
+file is updated.
+UFS only stores the flag, and relies on the application to change it when
+needed.
+.It Dv UF_HIDDEN
+The file may be hidden from directory listings at the application's
+discretion.
+The file has the DOS, Windows and CIFS FILE_ATTRIBUTE_HIDDEN attribute.
+.It Dv UF_IMMUTABLE
+The file may not be changed.
+.It Dv UF_NODUMP
+Do not dump the file.
+.It Dv UF_NOUNLINK
+The file may not be renamed or deleted.
+.It Dv UF_OFFLINE
+The file is offline, or has the Windows and CIFS FILE_ATTRIBUTE_OFFLINE
+attribute.
+Filesystems in FreeBSD store and display this flag, but do not provide any
+special handling when it is set.
+.It Dv UF_OPAQUE
+The directory is opaque when viewed through a union stack.
+.It Dv UF_READONLY
+The file is read only, and may not be written or appended.
+Filesystems may use this flag to maintain compatibility with the DOS, Windows
+and CIFS FILE_ATTRIBUTE_READONLY attribute.
+.It Dv UF_REPARSE
+The file contains a Windows reparse point and has the Windows and CIFS
+FILE_ATTRIBUTE_REPARSE_POINT attribute.
+.It Dv UF_SPARSE
+The file has the Windows FILE_ATTRIBUTE_SPARSE_FILE attribute.
+This may also be used by a filesystem to indicate a sparse file.
+.It Dv UF_SYSTEM
+The file has the DOS, Windows and CIFS FILE_ATTRIBUTE_SYSTEM attribute.
+Filesystems in FreeBSD may store and display this flag, but do not provide
+any special handling when it is set.
.El
.Pp
If one of
@@ -162,6 +197,13 @@ the system is in single-user mode.
.Xr init 8
for details.)
.Pp
+The implementation of all flags is filesystem-dependent.
+See the description of the
+.Dv UF_ARCHIVE
+flag above for one example of the differences in behavior.
+Care should be exercised when writing applications to account for
+support or lack of support of these flags in various filesystems.
+.Pp
The
.Dv SF_SNAPSHOT
flag is maintained by the system and cannot be toggled.
diff --git a/lib/libutil/expand_number.c b/lib/libutil/expand_number.c
index 0a62c12..401e2d9 100644
--- a/lib/libutil/expand_number.c
+++ b/lib/libutil/expand_number.c
@@ -50,15 +50,22 @@ int
expand_number(const char *buf, uint64_t *num)
{
uint64_t number;
+ int saved_errno;
unsigned shift;
char *endptr;
+ saved_errno = errno;
+ errno = 0;
+
number = strtoumax(buf, &endptr, 0);
if (number == UINTMAX_MAX && errno == ERANGE) {
return (-1);
}
+ if (errno == 0)
+ errno = saved_errno;
+
if (endptr == buf) {
/* No valid digits. */
errno = EINVAL;
diff --git a/share/man/man9/atomic.9 b/share/man/man9/atomic.9
index 0baac45..a2c0a67 100644
--- a/share/man/man9/atomic.9
+++ b/share/man/man9/atomic.9
@@ -23,7 +23,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd September 27, 2005
+.Dd August 20, 2013
.Dt ATOMIC 9
.Os
.Sh NAME
@@ -62,6 +62,10 @@
.Fn atomic_subtract_[acq_|rel_]<type> "volatile <type> *p" "<type> v"
.Ft void
.Fn atomic_store_rel_<type> "volatile <type> *p" "<type> v"
+.Ft <type>
+.Fn atomic_swap_<type> "volatile <type> *p" "<type> v"
+.Ft int
+.Fn atomic_testandset_<type> "volatile <type> *p" "u_int v"
.Sh DESCRIPTION
Each of the atomic operations is guaranteed to be atomic in the presence of
interrupts.
@@ -184,9 +188,9 @@ This section describes the semantics of each operation using a C like notation.
.Bd -literal -compact
if (*dst == old) {
*dst = new;
- return 1;
+ return (1);
} else
- return 0;
+ return (0);
.Ed
.El
.Pp
@@ -203,7 +207,7 @@ and
.Bd -literal -compact
tmp = *p;
*p += v;
-return tmp;
+return (tmp);
.Ed
.El
.Pp
@@ -216,9 +220,9 @@ and
.Dq Li 32
and do not have any variants with memory barriers at this time.
.Bl -hang
-.It Fn atomic_load addr
+.It Fn atomic_load p
.Bd -literal -compact
-return (*addr)
+return (*p);
.Ed
.El
.Pp
@@ -226,11 +230,11 @@ The
.Fn atomic_load
functions are only provided with acquire memory barriers.
.Bl -hang
-.It Fn atomic_readandclear addr
+.It Fn atomic_readandclear p
.Bd -literal -compact
-temp = *addr;
-*addr = 0;
-return (temp);
+tmp = *p;
+*p = 0;
+return (tmp);
.Ed
.El
.Pp
@@ -243,8 +247,7 @@ functions are not implemented for the types
.Dq Li 8 ,
and
.Dq Li 16
-and do
-not have any variants with memory barriers at this time.
+and do not have any variants with memory barriers at this time.
.Bl -hang
.It Fn atomic_set p v
.Bd -literal -compact
@@ -264,6 +267,44 @@ The
.Fn atomic_store
functions are only provided with release memory barriers.
.Pp
+.Bl -hang
+.It Fn atomic_swap p v
+.Bd -literal -compact
+tmp = *p;
+*p = v;
+return (tmp);
+.Ed
+.El
+.Pp
+The
+.Fn atomic_swap
+functions are not implemented for the types
+.Dq Li char ,
+.Dq Li short ,
+.Dq Li ptr ,
+.Dq Li 8 ,
+and
+.Dq Li 16
+and do not have any variants with memory barriers at this time.
+.Bl -hang
+.It Fn atomic_testandset p v
+.Bd -literal -compact
+bit = 1 << (v % (sizeof(*p) * NBBY));
+tmp = (*p & bit) != 0;
+*p |= bit;
+return (tmp);
+.Ed
+.El
+.Pp
+The
+.Fn atomic_testandset
+functions are only implemented for the types
+.Dq Li int ,
+.Dq Li long
+and
+.Dq Li 32
+and do not have any variants with memory barriers at this time.
+.Pp
The type
.Dq Li 64
is currently not implemented for any of the atomic operations on the
@@ -275,15 +316,17 @@ architectures.
.Sh RETURN VALUES
The
.Fn atomic_cmpset
-function
-returns the result of the compare operation.
+function returns the result of the compare operation.
The
.Fn atomic_fetchadd ,
.Fn atomic_load ,
+.Fn atomic_readandclear ,
and
-.Fn atomic_readandclear
-functions
-return the value at the specified address.
+.Fn atomic_swap
+functions return the value at the specified address.
+The
+.Fn atomic_testandset
+function returns the result of the test operation.
.Sh EXAMPLES
This example uses the
.Fn atomic_cmpset_acq_ptr
@@ -354,3 +397,9 @@ The
.Fn atomic_fetchadd
operations were added in
.Fx 6.0 .
+The
+.Fn atomic_swap
+and
+.Fn atomic_testandset
+operations were added in
+.Fx 10.0 .
diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC
index 3068a8a0..08865a8 100644
--- a/sys/amd64/conf/GENERIC
+++ b/sys/amd64/conf/GENERIC
@@ -293,8 +293,8 @@ device wpi # Intel 3945ABG wireless NICs.
# Pseudo devices.
device loop # Network loopback
device random # Entropy device
-options PADLOCK_RNG # VIA Padlock RNG
-options RDRAND_RNG # Intel Bull Mountain RNG
+device padlock_rng # VIA Padlock RNG
+device rdrand_rng # Intel Bull Mountain RNG
device ether # Ethernet support
device vlan # 802.1Q VLAN support
device tun # Packet tunnel.
diff --git a/sys/amd64/conf/NOTES b/sys/amd64/conf/NOTES
index 7d58541..95d4ce0 100644
--- a/sys/amd64/conf/NOTES
+++ b/sys/amd64/conf/NOTES
@@ -496,6 +496,8 @@ device vpd
device asmc
#device si
device tpm
+device padlock_rng # VIA Padlock RNG
+device rdrand_rng # Intel Bull Mountain RNG
#
# Laptop/Notebook options:
diff --git a/sys/amd64/include/atomic.h b/sys/amd64/include/atomic.h
index 11e7b57..9110dc5 100644
--- a/sys/amd64/include/atomic.h
+++ b/sys/amd64/include/atomic.h
@@ -54,12 +54,14 @@
* atomic_clear_int(P, V) (*(u_int *)(P) &= ~(V))
* atomic_add_int(P, V) (*(u_int *)(P) += (V))
* atomic_subtract_int(P, V) (*(u_int *)(P) -= (V))
+ * atomic_swap_int(P, V) (return (*(u_int *)(P)); *(u_int *)(P) = (V);)
* atomic_readandclear_int(P) (return (*(u_int *)(P)); *(u_int *)(P) = 0;)
*
* atomic_set_long(P, V) (*(u_long *)(P) |= (V))
* atomic_clear_long(P, V) (*(u_long *)(P) &= ~(V))
* atomic_add_long(P, V) (*(u_long *)(P) += (V))
* atomic_subtract_long(P, V) (*(u_long *)(P) -= (V))
+ * atomic_swap_long(P, V) (return (*(u_long *)(P)); *(u_long *)(P) = (V);)
* atomic_readandclear_long(P) (return (*(u_long *)(P)); *(u_long *)(P) = 0;)
*/
@@ -80,6 +82,8 @@ int atomic_cmpset_int(volatile u_int *dst, u_int expect, u_int src);
int atomic_cmpset_long(volatile u_long *dst, u_long expect, u_long src);
u_int atomic_fetchadd_int(volatile u_int *p, u_int v);
u_long atomic_fetchadd_long(volatile u_long *p, u_long v);
+int atomic_testandset_int(volatile u_int *p, u_int v);
+int atomic_testandset_long(volatile u_long *p, u_int v);
#define ATOMIC_LOAD(TYPE, LOP) \
u_##TYPE atomic_load_acq_##TYPE(volatile u_##TYPE *p)
@@ -138,15 +142,14 @@ atomic_cmpset_int(volatile u_int *dst, u_int expect, u_int src)
__asm __volatile(
" " MPLOCKED " "
- " cmpxchgl %2,%1 ; "
+ " cmpxchgl %3,%1 ; "
" sete %0 ; "
"# atomic_cmpset_int"
- : "=a" (res), /* 0 */
- "+m" (*dst) /* 1 */
- : "r" (src), /* 2 */
- "a" (expect) /* 3 */
+ : "=q" (res), /* 0 */
+ "+m" (*dst), /* 1 */
+ "+a" (expect) /* 2 */
+ : "r" (src) /* 3 */
: "memory", "cc");
-
return (res);
}
@@ -157,15 +160,14 @@ atomic_cmpset_long(volatile u_long *dst, u_long expect, u_long src)
__asm __volatile(
" " MPLOCKED " "
- " cmpxchgq %2,%1 ; "
+ " cmpxchgq %3,%1 ; "
" sete %0 ; "
"# atomic_cmpset_long"
- : "=a" (res), /* 0 */
- "+m" (*dst) /* 1 */
- : "r" (src), /* 2 */
- "a" (expect) /* 3 */
+ : "=q" (res), /* 0 */
+ "+m" (*dst), /* 1 */
+ "+a" (expect) /* 2 */
+ : "r" (src) /* 3 */
: "memory", "cc");
-
return (res);
}
@@ -205,6 +207,40 @@ atomic_fetchadd_long(volatile u_long *p, u_long v)
return (v);
}
+static __inline int
+atomic_testandset_int(volatile u_int *p, u_int v)
+{
+ u_char res;
+
+ __asm __volatile(
+ " " MPLOCKED " "
+ " btsl %2,%1 ; "
+ " setc %0 ; "
+ "# atomic_testandset_int"
+ : "=q" (res), /* 0 */
+ "+m" (*p) /* 1 */
+ : "Ir" (v & 0x1f) /* 2 */
+ : "cc");
+ return (res);
+}
+
+static __inline int
+atomic_testandset_long(volatile u_long *p, u_int v)
+{
+ u_char res;
+
+ __asm __volatile(
+ " " MPLOCKED " "
+ " btsq %2,%1 ; "
+ " setc %0 ; "
+ "# atomic_testandset_long"
+ : "=q" (res), /* 0 */
+ "+m" (*p) /* 1 */
+ : "Jr" ((u_long)(v & 0x3f)) /* 2 */
+ : "cc");
+ return (res);
+}
+
/*
* We assume that a = b will do atomic loads and stores. Due to the
* IA32 memory model, a simple store guarantees release semantics.
@@ -251,7 +287,6 @@ atomic_load_acq_##TYPE(volatile u_##TYPE *p) \
: "=a" (res), /* 0 */ \
"+m" (*p) /* 1 */ \
: : "memory", "cc"); \
- \
return (res); \
} \
struct __hack
@@ -296,43 +331,37 @@ ATOMIC_STORE(long);
#ifndef WANT_FUNCTIONS
-/* Read the current value and store a zero in the destination. */
+/* Read the current value and store a new value in the destination. */
#ifdef __GNUCLIKE_ASM
static __inline u_int
-atomic_readandclear_int(volatile u_int *p)
+atomic_swap_int(volatile u_int *p, u_int v)
{
- u_int res;
- res = 0;
__asm __volatile(
" xchgl %1,%0 ; "
- "# atomic_readandclear_int"
- : "+r" (res), /* 0 */
+ "# atomic_swap_int"
+ : "+r" (v), /* 0 */
"+m" (*p)); /* 1 */
-
- return (res);
+ return (v);
}
static __inline u_long
-atomic_readandclear_long(volatile u_long *p)
+atomic_swap_long(volatile u_long *p, u_long v)
{
- u_long res;
- res = 0;
__asm __volatile(
" xchgq %1,%0 ; "
- "# atomic_readandclear_long"
- : "+r" (res), /* 0 */
+ "# atomic_swap_long"
+ : "+r" (v), /* 0 */
"+m" (*p)); /* 1 */
-
- return (res);
+ return (v);
}
#else /* !__GNUCLIKE_ASM */
-u_int atomic_readandclear_int(volatile u_int *p);
-u_long atomic_readandclear_long(volatile u_long *p);
+u_int atomic_swap_int(volatile u_int *p, u_int v);
+u_long atomic_swap_long(volatile u_long *p, u_long v);
#endif /* __GNUCLIKE_ASM */
@@ -376,6 +405,9 @@ u_long atomic_readandclear_long(volatile u_long *p);
#define atomic_cmpset_acq_long atomic_cmpset_long
#define atomic_cmpset_rel_long atomic_cmpset_long
+#define atomic_readandclear_int(p) atomic_swap_int(p, 0)
+#define atomic_readandclear_long(p) atomic_swap_long(p, 0)
+
/* Operations on 8-bit bytes. */
#define atomic_set_8 atomic_set_char
#define atomic_set_acq_8 atomic_set_acq_char
@@ -426,8 +458,10 @@ u_long atomic_readandclear_long(volatile u_long *p);
#define atomic_cmpset_32 atomic_cmpset_int
#define atomic_cmpset_acq_32 atomic_cmpset_acq_int
#define atomic_cmpset_rel_32 atomic_cmpset_rel_int
+#define atomic_swap_32 atomic_swap_int
#define atomic_readandclear_32 atomic_readandclear_int
#define atomic_fetchadd_32 atomic_fetchadd_int
+#define atomic_testandset_32 atomic_testandset_int
/* Operations on 64-bit quad words. */
#define atomic_set_64 atomic_set_long
@@ -447,7 +481,9 @@ u_long atomic_readandclear_long(volatile u_long *p);
#define atomic_cmpset_64 atomic_cmpset_long
#define atomic_cmpset_acq_64 atomic_cmpset_acq_long
#define atomic_cmpset_rel_64 atomic_cmpset_rel_long
+#define atomic_swap_64 atomic_swap_long
#define atomic_readandclear_64 atomic_readandclear_long
+#define atomic_testandset_64 atomic_testandset_long
/* Operations on pointers. */
#define atomic_set_ptr atomic_set_long
@@ -467,6 +503,7 @@ u_long atomic_readandclear_long(volatile u_long *p);
#define atomic_cmpset_ptr atomic_cmpset_long
#define atomic_cmpset_acq_ptr atomic_cmpset_acq_long
#define atomic_cmpset_rel_ptr atomic_cmpset_rel_long
+#define atomic_swap_ptr atomic_swap_long
#define atomic_readandclear_ptr atomic_readandclear_long
#endif /* !WANT_FUNCTIONS */
diff --git a/sys/amd64/include/pmap.h b/sys/amd64/include/pmap.h
index 46d126d..aacb9ba 100644
--- a/sys/amd64/include/pmap.h
+++ b/sys/amd64/include/pmap.h
@@ -206,41 +206,14 @@ extern u_int64_t KPML4phys; /* physical address of kernel level 4 */
pt_entry_t *vtopte(vm_offset_t);
#define vtophys(va) pmap_kextract(((vm_offset_t) (va)))
-static __inline pt_entry_t
-pte_load(pt_entry_t *ptep)
-{
- pt_entry_t r;
-
- r = *ptep;
- return (r);
-}
-
-static __inline pt_entry_t
-pte_load_store(pt_entry_t *ptep, pt_entry_t pte)
-{
- pt_entry_t r;
-
- __asm __volatile(
- "xchgq %0,%1"
- : "=m" (*ptep),
- "=r" (r)
- : "1" (pte),
- "m" (*ptep));
- return (r);
-}
-
-#define pte_load_clear(pte) atomic_readandclear_long(pte)
-
-static __inline void
-pte_store(pt_entry_t *ptep, pt_entry_t pte)
-{
-
- *ptep = pte;
-}
-
-#define pte_clear(ptep) pte_store((ptep), (pt_entry_t)0ULL)
-
-#define pde_store(pdep, pde) pte_store((pdep), (pde))
+#define pte_load_store(ptep, pte) atomic_swap_long(ptep, pte)
+#define pte_load_clear(ptep) atomic_swap_long(ptep, 0)
+#define pte_store(ptep, pte) do { \
+ *(u_long *)(ptep) = (u_long)(pte); \
+} while (0)
+#define pte_clear(ptep) pte_store(ptep, 0)
+
+#define pde_store(pdep, pde) pte_store(pdep, pde)
extern pt_entry_t pg_nx;
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
index 9a109c7..6dfca35 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
@@ -6071,6 +6071,14 @@ zfs_freebsd_getattr(ap)
XVA_SET_REQ(&xvap, XAT_APPENDONLY);
XVA_SET_REQ(&xvap, XAT_NOUNLINK);
XVA_SET_REQ(&xvap, XAT_NODUMP);
+ XVA_SET_REQ(&xvap, XAT_READONLY);
+ XVA_SET_REQ(&xvap, XAT_ARCHIVE);
+ XVA_SET_REQ(&xvap, XAT_SYSTEM);
+ XVA_SET_REQ(&xvap, XAT_HIDDEN);
+ XVA_SET_REQ(&xvap, XAT_REPARSE);
+ XVA_SET_REQ(&xvap, XAT_OFFLINE);
+ XVA_SET_REQ(&xvap, XAT_SPARSE);
+
error = zfs_getattr(ap->a_vp, (vattr_t *)&xvap, 0, ap->a_cred, NULL);
if (error != 0)
return (error);
@@ -6086,8 +6094,23 @@ zfs_freebsd_getattr(ap)
xvap.xva_xoptattrs.xoa_appendonly);
FLAG_CHECK(SF_NOUNLINK, XAT_NOUNLINK,
xvap.xva_xoptattrs.xoa_nounlink);
+ FLAG_CHECK(UF_ARCHIVE, XAT_ARCHIVE,
+ xvap.xva_xoptattrs.xoa_archive);
FLAG_CHECK(UF_NODUMP, XAT_NODUMP,
xvap.xva_xoptattrs.xoa_nodump);
+ FLAG_CHECK(UF_READONLY, XAT_READONLY,
+ xvap.xva_xoptattrs.xoa_readonly);
+ FLAG_CHECK(UF_SYSTEM, XAT_SYSTEM,
+ xvap.xva_xoptattrs.xoa_system);
+ FLAG_CHECK(UF_HIDDEN, XAT_HIDDEN,
+ xvap.xva_xoptattrs.xoa_hidden);
+ FLAG_CHECK(UF_REPARSE, XAT_REPARSE,
+ xvap.xva_xoptattrs.xoa_reparse);
+ FLAG_CHECK(UF_OFFLINE, XAT_OFFLINE,
+ xvap.xva_xoptattrs.xoa_offline);
+ FLAG_CHECK(UF_SPARSE, XAT_SPARSE,
+ xvap.xva_xoptattrs.xoa_sparse);
+
#undef FLAG_CHECK
*vap = xvap.xva_vattr;
vap->va_flags = fflags;
@@ -6125,7 +6148,16 @@ zfs_freebsd_setattr(ap)
return (EOPNOTSUPP);
fflags = vap->va_flags;
- if ((fflags & ~(SF_IMMUTABLE|SF_APPEND|SF_NOUNLINK|UF_NODUMP)) != 0)
+ /*
+ * XXX KDM
+ * We need to figure out whether it makes sense to allow
+ * UF_REPARSE through, since we don't really have other
+ * facilities to handle reparse points and zfs_setattr()
+ * doesn't currently allow setting that attribute anyway.
+ */
+ if ((fflags & ~(SF_IMMUTABLE|SF_APPEND|SF_NOUNLINK|UF_ARCHIVE|
+ UF_NODUMP|UF_SYSTEM|UF_HIDDEN|UF_READONLY|UF_REPARSE|
+ UF_OFFLINE|UF_SPARSE)) != 0)
return (EOPNOTSUPP);
/*
* Unprivileged processes are not permitted to unset system
@@ -6177,8 +6209,22 @@ zfs_freebsd_setattr(ap)
xvap.xva_xoptattrs.xoa_appendonly);
FLAG_CHANGE(SF_NOUNLINK, ZFS_NOUNLINK, XAT_NOUNLINK,
xvap.xva_xoptattrs.xoa_nounlink);
+ FLAG_CHANGE(UF_ARCHIVE, ZFS_ARCHIVE, XAT_ARCHIVE,
+ xvap.xva_xoptattrs.xoa_archive);
FLAG_CHANGE(UF_NODUMP, ZFS_NODUMP, XAT_NODUMP,
xvap.xva_xoptattrs.xoa_nodump);
+ FLAG_CHANGE(UF_READONLY, ZFS_READONLY, XAT_READONLY,
+ xvap.xva_xoptattrs.xoa_readonly);
+ FLAG_CHANGE(UF_SYSTEM, ZFS_SYSTEM, XAT_SYSTEM,
+ xvap.xva_xoptattrs.xoa_system);
+ FLAG_CHANGE(UF_HIDDEN, ZFS_HIDDEN, XAT_HIDDEN,
+ xvap.xva_xoptattrs.xoa_hidden);
+ FLAG_CHANGE(UF_REPARSE, ZFS_REPARSE, XAT_REPARSE,
+ xvap.xva_xoptattrs.xoa_hidden);
+ FLAG_CHANGE(UF_OFFLINE, ZFS_OFFLINE, XAT_OFFLINE,
+ xvap.xva_xoptattrs.xoa_offline);
+ FLAG_CHANGE(UF_SPARSE, ZFS_SPARSE, XAT_SPARSE,
+ xvap.xva_xoptattrs.xoa_sparse);
#undef FLAG_CHANGE
}
return (zfs_setattr(vp, (vattr_t *)&xvap, 0, cred, NULL));
diff --git a/sys/cddl/dev/dtrace/powerpc/dtrace_asm.S b/sys/cddl/dev/dtrace/powerpc/dtrace_asm.S
index 79079e5..5676360 100644
--- a/sys/cddl/dev/dtrace/powerpc/dtrace_asm.S
+++ b/sys/cddl/dev/dtrace/powerpc/dtrace_asm.S
@@ -125,13 +125,13 @@ void
dtrace_copy(uintptr_t src, uintptr_t dest, size_t size)
*/
ASENTRY_NOPROF(dtrace_copy)
- addme %r7,%r3
- addme %r8,%r4
+ subi %r7,%r3,1
+ subi %r8,%r4,1
+ mtctr %r5
1:
lbzu %r3,1(%r7)
stbu %r3,1(%r8)
- addme %r5,%r5
- beq 2f
+ bdnz 1b
2:
blr
END(dtrace_copy)
diff --git a/sys/conf/options.amd64 b/sys/conf/options.amd64
index 90348b7..31d1650 100644
--- a/sys/conf/options.amd64
+++ b/sys/conf/options.amd64
@@ -68,7 +68,3 @@ XENHVM opt_global.h
# options for the Intel C600 SAS driver (isci)
ISCI_LOGGING opt_isci.h
-
-# hw random number generators for random(4)
-PADLOCK_RNG opt_cpu.h
-RDRAND_RNG opt_cpu.h
diff --git a/sys/conf/options.i386 b/sys/conf/options.i386
index 059a637..3638266 100644
--- a/sys/conf/options.i386
+++ b/sys/conf/options.i386
@@ -123,7 +123,3 @@ XENHVM opt_global.h
# options for the Intel C600 SAS driver (isci)
ISCI_LOGGING opt_isci.h
-
-# hw random number generators for random(4)
-PADLOCK_RNG opt_cpu.h
-RDRAND_RNG opt_cpu.h
diff --git a/sys/dev/hwpmc/pmc_events.h b/sys/dev/hwpmc/pmc_events.h
index 9009a61..5358ae2 100644
--- a/sys/dev/hwpmc/pmc_events.h
+++ b/sys/dev/hwpmc/pmc_events.h
@@ -3304,7 +3304,7 @@ __PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HITM", \
IAP_EVENT_D2H_04H) \
__PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_NONE", \
IAP_EVENT_D2H_08H) \
-__PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_HIT_RETIRED.LLC_MISS", \
+__PMC_EV_ALIAS("MEM_LOAD_UOPS_MISC_RETIRED.LLC_MISS", \
IAP_EVENT_D4H_02H) \
__PMC_EV_ALIAS("L2_TRANS.DEMAND_DATA_RD", IAP_EVENT_F0H_01H) \
__PMC_EV_ALIAS("L2_TRANS.RFO", IAP_EVENT_F0H_02H) \
@@ -3538,7 +3538,7 @@ __PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_NONE", \
IAP_EVENT_D2H_08H) \
__PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_HIT_RETIRED.ALL", \
IAP_EVENT_D2H_0FH) \
-__PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_HIT_RETIRED.LLC_MISS", \
+__PMC_EV_ALIAS("MEM_LOAD_UOPS_MISC_RETIRED.LLC_MISS", \
IAP_EVENT_D4H_02H) \
__PMC_EV_ALIAS("MEM_LOAD_UOPS_LLC_MISS_RETIRED.LOCAL_DRAM", \
IAP_EVENT_D3H_01H) \
diff --git a/sys/dev/mps/mps_sas.c b/sys/dev/mps/mps_sas.c
index 6e5252b..b6ee542 100644
--- a/sys/dev/mps/mps_sas.c
+++ b/sys/dev/mps/mps_sas.c
@@ -2103,7 +2103,7 @@ mpssas_scsiio_complete(struct mps_softc *sc, struct mps_command *cm)
cm->cm_targ->completed++;
cm->cm_targ->outstanding--;
TAILQ_REMOVE(&cm->cm_targ->commands, cm, cm_link);
- ccb->ccb_h.status |= ~(CAM_STATUS_MASK | CAM_SIM_QUEUED);
+ ccb->ccb_h.status &= ~(CAM_STATUS_MASK | CAM_SIM_QUEUED);
if (cm->cm_state == MPS_CM_STATE_TIMEDOUT) {
TAILQ_REMOVE(&cm->cm_targ->timedout_commands, cm, cm_recovery);
@@ -2145,7 +2145,7 @@ mpssas_scsiio_complete(struct mps_softc *sc, struct mps_command *cm)
* because there can be no reply when we haven't actually
* gone out to the hardware.
*/
- ccb->ccb_h.status |= CAM_REQUEUE_REQ;
+ ccb->ccb_h.status = CAM_REQUEUE_REQ;
/*
* Currently the only error included in the mask is
diff --git a/sys/fs/msdosfs/msdosfs_denode.c b/sys/fs/msdosfs/msdosfs_denode.c
index 501604a..b2a51ea 100644
--- a/sys/fs/msdosfs/msdosfs_denode.c
+++ b/sys/fs/msdosfs/msdosfs_denode.c
@@ -304,8 +304,8 @@ deupdat(dep, waitfor)
if ((dep->de_flag & DE_MODIFIED) == 0 && waitfor == 0)
return (0);
dep->de_flag &= ~DE_MODIFIED;
- if (dep->de_Attributes & ATTR_DIRECTORY)
- return (0);
+ if (DETOV(dep)->v_vflag & VV_ROOT)
+ return (EINVAL);
if (dep->de_refcnt <= 0)
return (0);
error = readde(dep, &bp, &dirp);
diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c
index da9a5df..04cb372 100644
--- a/sys/fs/msdosfs/msdosfs_vnops.c
+++ b/sys/fs/msdosfs/msdosfs_vnops.c
@@ -172,8 +172,7 @@ msdosfs_create(ap)
if (error)
goto bad;
- ndirent.de_Attributes = (ap->a_vap->va_mode & VWRITE) ?
- ATTR_ARCHIVE : ATTR_ARCHIVE | ATTR_READONLY;
+ ndirent.de_Attributes = ATTR_ARCHIVE;
ndirent.de_LowerCase = 0;
ndirent.de_StartCluster = 0;
ndirent.de_FileSize = 0;
@@ -256,8 +255,7 @@ msdosfs_access(ap)
mode_t file_mode;
accmode_t accmode = ap->a_accmode;
- file_mode = (S_IXUSR|S_IXGRP|S_IXOTH) | (S_IRUSR|S_IRGRP|S_IROTH) |
- ((dep->de_Attributes & ATTR_READONLY) ? 0 : (S_IWUSR|S_IWGRP|S_IWOTH));
+ file_mode = S_IRWXU|S_IRWXG|S_IRWXO;
file_mode &= (vp->v_type == VDIR ? pmp->pm_dirmask : pmp->pm_mask);
/*
@@ -266,8 +264,8 @@ msdosfs_access(ap)
*/
if (accmode & VWRITE) {
switch (vp->v_type) {
- case VDIR:
case VREG:
+ case VDIR:
if (vp->v_mount->mnt_flag & MNT_RDONLY)
return (EROFS);
break;
@@ -322,10 +320,7 @@ msdosfs_getattr(ap)
else
vap->va_fileid = (long)fileid;
- if ((dep->de_Attributes & ATTR_READONLY) == 0)
- mode = S_IRWXU|S_IRWXG|S_IRWXO;
- else
- mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
+ mode = S_IRWXU|S_IRWXG|S_IRWXO;
vap->va_mode = mode &
(ap->a_vp->v_type == VDIR ? pmp->pm_dirmask : pmp->pm_mask);
vap->va_uid = pmp->pm_uid;
@@ -345,8 +340,14 @@ msdosfs_getattr(ap)
vap->va_birthtime.tv_nsec = 0;
}
vap->va_flags = 0;
- if ((dep->de_Attributes & ATTR_ARCHIVE) == 0)
- vap->va_flags |= SF_ARCHIVED;
+ if (dep->de_Attributes & ATTR_ARCHIVE)
+ vap->va_flags |= UF_ARCHIVE;
+ if (dep->de_Attributes & ATTR_HIDDEN)
+ vap->va_flags |= UF_HIDDEN;
+ if (dep->de_Attributes & ATTR_READONLY)
+ vap->va_flags |= UF_READONLY;
+ if (dep->de_Attributes & ATTR_SYSTEM)
+ vap->va_flags |= UF_SYSTEM;
vap->va_gen = 0;
vap->va_blocksize = pmp->pm_bpcluster;
vap->va_bytes =
@@ -395,6 +396,18 @@ msdosfs_setattr(ap)
#endif
return (EINVAL);
}
+
+ /*
+ * We don't allow setting attributes on the root directory.
+ * The special case for the root directory is because before
+ * FAT32, the root directory didn't have an entry for itself
+ * (and was otherwise special). With FAT32, the root
+ * directory is not so special, but still doesn't have an
+ * entry for itself.
+ */
+ if (vp->v_vflag & VV_ROOT)
+ return (EINVAL);
+
if (vap->va_flags != VNOVAL) {
if (vp->v_mount->mnt_flag & MNT_RDONLY)
return (EROFS);
@@ -408,24 +421,29 @@ msdosfs_setattr(ap)
* attributes. We ignored the access time and the
* read and execute bits. We were strict for the other
* attributes.
- *
- * Here we are strict, stricter than ufs in not allowing
- * users to attempt to set SF_SETTABLE bits or anyone to
- * set unsupported bits. However, we ignore attempts to
- * set ATTR_ARCHIVE for directories `cp -pr' from a more
- * sensible filesystem attempts it a lot.
*/
- if (vap->va_flags & SF_SETTABLE) {
- error = priv_check_cred(cred, PRIV_VFS_SYSFLAGS, 0);
- if (error)
- return (error);
- }
- if (vap->va_flags & ~SF_ARCHIVED)
+ if (vap->va_flags & ~(UF_ARCHIVE | UF_HIDDEN | UF_READONLY |
+ UF_SYSTEM))
return EOPNOTSUPP;
- if (vap->va_flags & SF_ARCHIVED)
- dep->de_Attributes &= ~ATTR_ARCHIVE;
- else if (!(dep->de_Attributes & ATTR_DIRECTORY))
+ if (vap->va_flags & UF_ARCHIVE)
dep->de_Attributes |= ATTR_ARCHIVE;
+ else
+ dep->de_Attributes &= ~ATTR_ARCHIVE;
+ if (vap->va_flags & UF_HIDDEN)
+ dep->de_Attributes |= ATTR_HIDDEN;
+ else
+ dep->de_Attributes &= ~ATTR_HIDDEN;
+ /* We don't allow changing the readonly bit on directories. */
+ if (vp->v_type != VDIR) {
+ if (vap->va_flags & UF_READONLY)
+ dep->de_Attributes |= ATTR_READONLY;
+ else
+ dep->de_Attributes &= ~ATTR_READONLY;
+ }
+ if (vap->va_flags & UF_SYSTEM)
+ dep->de_Attributes |= ATTR_SYSTEM;
+ else
+ dep->de_Attributes &= ~ATTR_SYSTEM;
dep->de_flag |= DE_MODIFIED;
}
@@ -489,21 +507,24 @@ msdosfs_setattr(ap)
error = VOP_ACCESS(vp, VWRITE, cred, td);
} else
error = VOP_ACCESS(vp, VADMIN, cred, td);
- if (vp->v_type != VDIR) {
- if ((pmp->pm_flags & MSDOSFSMNT_NOWIN95) == 0 &&
- vap->va_atime.tv_sec != VNOVAL) {
- dep->de_flag &= ~DE_ACCESS;
- timespec2fattime(&vap->va_atime, 0,
- &dep->de_ADate, NULL, NULL);
- }
- if (vap->va_mtime.tv_sec != VNOVAL) {
- dep->de_flag &= ~DE_UPDATE;
- timespec2fattime(&vap->va_mtime, 0,
- &dep->de_MDate, &dep->de_MTime, NULL);
- }
- dep->de_Attributes |= ATTR_ARCHIVE;
- dep->de_flag |= DE_MODIFIED;
+ if ((pmp->pm_flags & MSDOSFSMNT_NOWIN95) == 0 &&
+ vap->va_atime.tv_sec != VNOVAL) {
+ dep->de_flag &= ~DE_ACCESS;
+ timespec2fattime(&vap->va_atime, 0,
+ &dep->de_ADate, NULL, NULL);
}
+ if (vap->va_mtime.tv_sec != VNOVAL) {
+ dep->de_flag &= ~DE_UPDATE;
+ timespec2fattime(&vap->va_mtime, 0,
+ &dep->de_MDate, &dep->de_MTime, NULL);
+ }
+ /*
+ * We don't set the archive bit when modifying the time of
+ * a directory to emulate the Windows/DOS behavior.
+ */
+ if (vp->v_type != VDIR)
+ dep->de_Attributes |= ATTR_ARCHIVE;
+ dep->de_flag |= DE_MODIFIED;
}
/*
* DOS files only have the ability to have their writability
diff --git a/sys/fs/smbfs/smbfs_node.c b/sys/fs/smbfs/smbfs_node.c
index 1b55ff3..05d19e9 100644
--- a/sys/fs/smbfs/smbfs_node.c
+++ b/sys/fs/smbfs/smbfs_node.c
@@ -370,10 +370,13 @@ smbfs_attr_cachelookup(struct vnode *vp, struct vattr *va)
if (diff > 2) /* XXX should be configurable */
return ENOENT;
va->va_type = vp->v_type; /* vnode type (for create) */
+ va->va_flags = 0; /* flags defined for file */
if (vp->v_type == VREG) {
va->va_mode = smp->sm_file_mode; /* files access mode and type */
- if (np->n_dosattr & SMB_FA_RDONLY)
+ if (np->n_dosattr & SMB_FA_RDONLY) {
va->va_mode &= ~(S_IWUSR|S_IWGRP|S_IWOTH);
+ va->va_flags |= UF_READONLY;
+ }
} else if (vp->v_type == VDIR) {
va->va_mode = smp->sm_dir_mode; /* files access mode and type */
} else
@@ -390,7 +393,15 @@ smbfs_attr_cachelookup(struct vnode *vp, struct vattr *va)
va->va_mtime = np->n_mtime;
va->va_atime = va->va_ctime = va->va_mtime; /* time file changed */
va->va_gen = VNOVAL; /* generation number of file */
- va->va_flags = 0; /* flags defined for file */
+ if (np->n_dosattr & SMB_FA_HIDDEN)
+ va->va_flags |= UF_HIDDEN;
+ if (np->n_dosattr & SMB_FA_SYSTEM)
+ va->va_flags |= UF_SYSTEM;
+ /*
+ * We don't set the archive bit for directories.
+ */
+ if ((vp->v_type != VDIR) && (np->n_dosattr & SMB_FA_ARCHIVE))
+ va->va_flags |= UF_ARCHIVE;
va->va_rdev = NODEV; /* device the special file represents */
va->va_bytes = va->va_size; /* bytes of disk space held by file */
va->va_filerev = 0; /* file modification number */
diff --git a/sys/fs/smbfs/smbfs_vnops.c b/sys/fs/smbfs/smbfs_vnops.c
index ef1dc65..8ea1198 100644
--- a/sys/fs/smbfs/smbfs_vnops.c
+++ b/sys/fs/smbfs/smbfs_vnops.c
@@ -305,16 +305,30 @@ smbfs_setattr(ap)
int old_n_dosattr;
SMBVDEBUG("\n");
- if (vap->va_flags != VNOVAL)
- return EOPNOTSUPP;
isreadonly = (vp->v_mount->mnt_flag & MNT_RDONLY);
/*
* Disallow write attempts if the filesystem is mounted read-only.
*/
if ((vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL ||
vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL ||
- vap->va_mode != (mode_t)VNOVAL) && isreadonly)
+ vap->va_mode != (mode_t)VNOVAL || vap->va_flags != VNOVAL) &&
+ isreadonly)
return EROFS;
+
+ /*
+ * We only support setting four flags. Don't allow setting others.
+ *
+ * We map UF_READONLY to SMB_FA_RDONLY, unlike the MacOS X version
+ * of this code, which maps both UF_IMMUTABLE AND SF_IMMUTABLE to
+ * SMB_FA_RDONLY. The immutable flags have different semantics
+ * than readonly, which is the reason for the difference.
+ */
+ if (vap->va_flags != VNOVAL) {
+ if (vap->va_flags & ~(UF_HIDDEN|UF_SYSTEM|UF_ARCHIVE|
+ UF_READONLY))
+ return EINVAL;
+ }
+
scred = smbfs_malloc_scred();
smb_makescred(scred, td, ap->a_cred);
if (vap->va_size != VNOVAL) {
@@ -353,12 +367,47 @@ smbfs_setattr(ap)
goto out;
}
}
- if (vap->va_mode != (mode_t)VNOVAL) {
+ if ((vap->va_flags != VNOVAL) || (vap->va_mode != (mode_t)VNOVAL)) {
old_n_dosattr = np->n_dosattr;
- if (vap->va_mode & S_IWUSR)
- np->n_dosattr &= ~SMB_FA_RDONLY;
- else
- np->n_dosattr |= SMB_FA_RDONLY;
+
+ if (vap->va_mode != (mode_t)VNOVAL) {
+ if (vap->va_mode & S_IWUSR)
+ np->n_dosattr &= ~SMB_FA_RDONLY;
+ else
+ np->n_dosattr |= SMB_FA_RDONLY;
+ }
+
+ if (vap->va_flags != VNOVAL) {
+ if (vap->va_flags & UF_HIDDEN)
+ np->n_dosattr |= SMB_FA_HIDDEN;
+ else
+ np->n_dosattr &= ~SMB_FA_HIDDEN;
+
+ if (vap->va_flags & UF_SYSTEM)
+ np->n_dosattr |= SMB_FA_SYSTEM;
+ else
+ np->n_dosattr &= ~SMB_FA_SYSTEM;
+
+ if (vap->va_flags & UF_ARCHIVE)
+ np->n_dosattr |= SMB_FA_ARCHIVE;
+ else
+ np->n_dosattr &= ~SMB_FA_ARCHIVE;
+
+ /*
+ * We only support setting the immutable / readonly
+ * bit for regular files. According to comments in
+ * the MacOS X version of this code, supporting the
+ * readonly bit on directories doesn't do the same
+ * thing in Windows as in Unix.
+ */
+ if (vp->v_type == VREG) {
+ if (vap->va_flags & UF_READONLY)
+ np->n_dosattr |= SMB_FA_RDONLY;
+ else
+ np->n_dosattr &= ~SMB_FA_RDONLY;
+ }
+ }
+
if (np->n_dosattr != old_n_dosattr) {
error = smbfs_smb_setpattr(np, np->n_dosattr, NULL, scred);
if (error)
diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC
index 7e8bb90..5e6bfd5 100644
--- a/sys/i386/conf/GENERIC
+++ b/sys/i386/conf/GENERIC
@@ -307,8 +307,8 @@ device wpi # Intel 3945ABG wireless NICs.
# Pseudo devices.
device loop # Network loopback
device random # Entropy device
-options PADLOCK_RNG # VIA Padlock RNG
-options RDRAND_RNG # Intel Bull Mountain RNG
+device padlock_rng # VIA Padlock RNG
+device rdrand_rng # Intel Bull Mountain RNG
device ether # Ethernet support
device vlan # 802.1Q VLAN support
device tun # Packet tunnel.
diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES
index 36744ab..3cb1264 100644
--- a/sys/i386/conf/NOTES
+++ b/sys/i386/conf/NOTES
@@ -850,6 +850,8 @@ hint.spic.0.port="0x10a0"
device asmc
#device si
device tpm
+device padlock_rng # VIA Padlock RNG
+device rdrand_rng # Intel Bull Mountain RNG
#
# Laptop/Notebook options:
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index f62854b..9a710e5 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -1548,21 +1548,6 @@ idle_sysctl(SYSCTL_HANDLER_ARGS)
SYSCTL_PROC(_machdep, OID_AUTO, idle, CTLTYPE_STRING | CTLFLAG_RW, 0, 0,
idle_sysctl, "A", "currently selected idle function");
-uint64_t (*atomic_load_acq_64)(volatile uint64_t *) =
- atomic_load_acq_64_i386;
-void (*atomic_store_rel_64)(volatile uint64_t *, uint64_t) =
- atomic_store_rel_64_i386;
-
-static void
-cpu_probe_cmpxchg8b(void)
-{
-
- if ((cpu_feature & CPUID_CX8) != 0) {
- atomic_load_acq_64 = atomic_load_acq_64_i586;
- atomic_store_rel_64 = atomic_store_rel_64_i586;
- }
-}
-
/*
* Reset registers to default values on exec.
*/
@@ -2824,7 +2809,6 @@ init386(first)
thread0.td_pcb->pcb_gsd = PCPU_GET(fsgs_gdt)[1];
cpu_probe_amdc1e();
- cpu_probe_cmpxchg8b();
}
#else
@@ -3115,7 +3099,6 @@ init386(first)
thread0.td_frame = &proc0_tf;
cpu_probe_amdc1e();
- cpu_probe_cmpxchg8b();
#ifdef FDT
x86_init_fdt();
diff --git a/sys/i386/include/atomic.h b/sys/i386/include/atomic.h
index 722aca4..0156b5b 100644
--- a/sys/i386/include/atomic.h
+++ b/sys/i386/include/atomic.h
@@ -32,6 +32,11 @@
#error this file needs sys/cdefs.h as a prerequisite
#endif
+#ifdef _KERNEL
+#include <machine/md_var.h>
+#include <machine/specialreg.h>
+#endif
+
#define mb() __asm __volatile("lock; addl $0,(%%esp)" : : : "memory", "cc")
#define wmb() __asm __volatile("lock; addl $0,(%%esp)" : : : "memory", "cc")
#define rmb() __asm __volatile("lock; addl $0,(%%esp)" : : : "memory", "cc")
@@ -54,12 +59,14 @@
* atomic_clear_int(P, V) (*(u_int *)(P) &= ~(V))
* atomic_add_int(P, V) (*(u_int *)(P) += (V))
* atomic_subtract_int(P, V) (*(u_int *)(P) -= (V))
+ * atomic_swap_int(P, V) (return (*(u_int *)(P)); *(u_int *)(P) = (V);)
* atomic_readandclear_int(P) (return (*(u_int *)(P)); *(u_int *)(P) = 0;)
*
* atomic_set_long(P, V) (*(u_long *)(P) |= (V))
* atomic_clear_long(P, V) (*(u_long *)(P) &= ~(V))
* atomic_add_long(P, V) (*(u_long *)(P) += (V))
* atomic_subtract_long(P, V) (*(u_long *)(P) -= (V))
+ * atomic_swap_long(P, V) (return (*(u_long *)(P)); *(u_long *)(P) = (V);)
* atomic_readandclear_long(P) (return (*(u_long *)(P)); *(u_long *)(P) = 0;)
*/
@@ -78,12 +85,18 @@ void atomic_##NAME##_barr_##TYPE(volatile u_##TYPE *p, u_##TYPE v)
int atomic_cmpset_int(volatile u_int *dst, u_int expect, u_int src);
u_int atomic_fetchadd_int(volatile u_int *p, u_int v);
+int atomic_testandset_int(volatile u_int *p, u_int v);
#define ATOMIC_LOAD(TYPE, LOP) \
u_##TYPE atomic_load_acq_##TYPE(volatile u_##TYPE *p)
#define ATOMIC_STORE(TYPE) \
void atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v)
+int atomic_cmpset_64(volatile uint64_t *, uint64_t, uint64_t);
+uint64_t atomic_load_acq_64(volatile uint64_t *);
+void atomic_store_rel_64(volatile uint64_t *, uint64_t);
+uint64_t atomic_swap_64(volatile uint64_t *, uint64_t);
+
#else /* !KLD_MODULE && __GNUCLIKE_ASM */
/*
@@ -121,85 +134,6 @@ atomic_##NAME##_barr_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\
} \
struct __hack
-#if defined(_KERNEL) && !defined(WANT_FUNCTIONS)
-
-/* I486 does not support SMP or CMPXCHG8B. */
-static __inline uint64_t
-atomic_load_acq_64_i386(volatile uint64_t *p)
-{
- volatile uint32_t *high, *low;
- uint64_t res;
-
- low = (volatile uint32_t *)p;
- high = (volatile uint32_t *)p + 1;
- __asm __volatile(
- " pushfl ; "
- " cli ; "
- " movl %1,%%eax ; "
- " movl %2,%%edx ; "
- " popfl"
- : "=&A" (res) /* 0 */
- : "m" (*low), /* 1 */
- "m" (*high) /* 2 */
- : "memory");
-
- return (res);
-}
-
-static __inline void
-atomic_store_rel_64_i386(volatile uint64_t *p, uint64_t v)
-{
- volatile uint32_t *high, *low;
-
- low = (volatile uint32_t *)p;
- high = (volatile uint32_t *)p + 1;
- __asm __volatile(
- " pushfl ; "
- " cli ; "
- " movl %%eax,%0 ; "
- " movl %%edx,%1 ; "
- " popfl"
- : "=m" (*low), /* 0 */
- "=m" (*high) /* 1 */
- : "A" (v) /* 2 */
- : "memory");
-}
-
-static __inline uint64_t
-atomic_load_acq_64_i586(volatile uint64_t *p)
-{
- uint64_t res;
-
- __asm __volatile(
- " movl %%ebx,%%eax ; "
- " movl %%ecx,%%edx ; "
- " " MPLOCKED " "
- " cmpxchg8b %1"
- : "=&A" (res), /* 0 */
- "+m" (*p) /* 1 */
- : : "memory", "cc");
-
- return (res);
-}
-
-static __inline void
-atomic_store_rel_64_i586(volatile uint64_t *p, uint64_t v)
-{
-
- __asm __volatile(
- " movl %%eax,%%ebx ; "
- " movl %%edx,%%ecx ; "
- "1: "
- " " MPLOCKED " "
- " cmpxchg8b %0 ; "
- " jne 1b"
- : "+m" (*p), /* 0 */
- "+A" (v) /* 1 */
- : : "ebx", "ecx", "memory", "cc");
-}
-
-#endif /* _KERNEL && !WANT_FUNCTIONS */
-
/*
* Atomic compare and set, used by the mutex functions
*
@@ -230,7 +164,6 @@ atomic_cmpset_int(volatile u_int *dst, u_int expect, u_int src)
: "r" (src), /* 2 */
"r" (expect) /* 3 */
: "memory");
-
return (res);
}
@@ -243,15 +176,14 @@ atomic_cmpset_int(volatile u_int *dst, u_int expect, u_int src)
__asm __volatile(
" " MPLOCKED " "
- " cmpxchgl %2,%1 ; "
+ " cmpxchgl %3,%1 ; "
" sete %0 ; "
"# atomic_cmpset_int"
- : "=a" (res), /* 0 */
- "+m" (*dst) /* 1 */
- : "r" (src), /* 2 */
- "a" (expect) /* 3 */
+ : "=q" (res), /* 0 */
+ "+m" (*dst), /* 1 */
+ "+a" (expect) /* 2 */
+ : "r" (src) /* 3 */
: "memory", "cc");
-
return (res);
}
@@ -275,6 +207,23 @@ atomic_fetchadd_int(volatile u_int *p, u_int v)
return (v);
}
+static __inline int
+atomic_testandset_int(volatile u_int *p, u_int v)
+{
+ u_char res;
+
+ __asm __volatile(
+ " " MPLOCKED " "
+ " btsl %2,%1 ; "
+ " setc %0 ; "
+ "# atomic_testandset_int"
+ : "=q" (res), /* 0 */
+ "+m" (*p) /* 1 */
+ : "Ir" (v & 0x1f) /* 2 */
+ : "cc");
+ return (res);
+}
+
/*
* We assume that a = b will do atomic loads and stores. Due to the
* IA32 memory model, a simple store guarantees release semantics.
@@ -321,13 +270,225 @@ atomic_load_acq_##TYPE(volatile u_##TYPE *p) \
: "=a" (res), /* 0 */ \
"+m" (*p) /* 1 */ \
: : "memory", "cc"); \
- \
return (res); \
} \
struct __hack
#endif /* _KERNEL && !SMP */
+#ifdef _KERNEL
+
+#ifdef WANT_FUNCTIONS
+int atomic_cmpset_64_i386(volatile uint64_t *, uint64_t, uint64_t);
+int atomic_cmpset_64_i586(volatile uint64_t *, uint64_t, uint64_t);
+uint64_t atomic_load_acq_64_i386(volatile uint64_t *);
+uint64_t atomic_load_acq_64_i586(volatile uint64_t *);
+void atomic_store_rel_64_i386(volatile uint64_t *, uint64_t);
+void atomic_store_rel_64_i586(volatile uint64_t *, uint64_t);
+uint64_t atomic_swap_64_i386(volatile uint64_t *, uint64_t);
+uint64_t atomic_swap_64_i586(volatile uint64_t *, uint64_t);
+#endif
+
+/* I486 does not support SMP or CMPXCHG8B. */
+static __inline int
+atomic_cmpset_64_i386(volatile uint64_t *dst, uint64_t expect, uint64_t src)
+{
+ volatile uint32_t *p;
+ u_char res;
+
+ p = (volatile uint32_t *)dst;
+ __asm __volatile(
+ " pushfl ; "
+ " cli ; "
+ " xorl %1,%%eax ; "
+ " xorl %2,%%edx ; "
+ " orl %%edx,%%eax ; "
+ " jne 1f ; "
+ " movl %4,%1 ; "
+ " movl %5,%2 ; "
+ "1: "
+ " sete %3 ; "
+ " popfl"
+ : "+A" (expect), /* 0 */
+ "+m" (*p), /* 1 */
+ "+m" (*(p + 1)), /* 2 */
+ "=q" (res) /* 3 */
+ : "r" ((uint32_t)src), /* 4 */
+ "r" ((uint32_t)(src >> 32)) /* 5 */
+ : "memory", "cc");
+ return (res);
+}
+
+static __inline uint64_t
+atomic_load_acq_64_i386(volatile uint64_t *p)
+{
+ volatile uint32_t *q;
+ uint64_t res;
+
+ q = (volatile uint32_t *)p;
+ __asm __volatile(
+ " pushfl ; "
+ " cli ; "
+ " movl %1,%%eax ; "
+ " movl %2,%%edx ; "
+ " popfl"
+ : "=&A" (res) /* 0 */
+ : "m" (*q), /* 1 */
+ "m" (*(q + 1)) /* 2 */
+ : "memory");
+ return (res);
+}
+
+static __inline void
+atomic_store_rel_64_i386(volatile uint64_t *p, uint64_t v)
+{
+ volatile uint32_t *q;
+
+ q = (volatile uint32_t *)p;
+ __asm __volatile(
+ " pushfl ; "
+ " cli ; "
+ " movl %%eax,%0 ; "
+ " movl %%edx,%1 ; "
+ " popfl"
+ : "=m" (*q), /* 0 */
+ "=m" (*(q + 1)) /* 1 */
+ : "A" (v) /* 2 */
+ : "memory");
+}
+
+static __inline uint64_t
+atomic_swap_64_i386(volatile uint64_t *p, uint64_t v)
+{
+ volatile uint32_t *q;
+ uint64_t res;
+
+ q = (volatile uint32_t *)p;
+ __asm __volatile(
+ " pushfl ; "
+ " cli ; "
+ " movl %1,%%eax ; "
+ " movl %2,%%edx ; "
+ " movl %4,%2 ; "
+ " movl %3,%1 ; "
+ " popfl"
+ : "=&A" (res), /* 0 */
+ "+m" (*q), /* 1 */
+ "+m" (*(q + 1)) /* 2 */
+ : "r" ((uint32_t)v), /* 3 */
+ "r" ((uint32_t)(v >> 32))); /* 4 */
+ return (res);
+}
+
+static __inline int
+atomic_cmpset_64_i586(volatile uint64_t *dst, uint64_t expect, uint64_t src)
+{
+ u_char res;
+
+ __asm __volatile(
+ " " MPLOCKED " "
+ " cmpxchg8b %1 ; "
+ " sete %0"
+ : "=q" (res), /* 0 */
+ "+m" (*dst), /* 1 */
+ "+A" (expect) /* 2 */
+ : "b" ((uint32_t)src), /* 3 */
+ "c" ((uint32_t)(src >> 32)) /* 4 */
+ : "memory", "cc");
+ return (res);
+}
+
+static __inline uint64_t
+atomic_load_acq_64_i586(volatile uint64_t *p)
+{
+ uint64_t res;
+
+ __asm __volatile(
+ " movl %%ebx,%%eax ; "
+ " movl %%ecx,%%edx ; "
+ " " MPLOCKED " "
+ " cmpxchg8b %1"
+ : "=&A" (res), /* 0 */
+ "+m" (*p) /* 1 */
+ : : "memory", "cc");
+ return (res);
+}
+
+static __inline void
+atomic_store_rel_64_i586(volatile uint64_t *p, uint64_t v)
+{
+
+ __asm __volatile(
+ " movl %%eax,%%ebx ; "
+ " movl %%edx,%%ecx ; "
+ "1: "
+ " " MPLOCKED " "
+ " cmpxchg8b %0 ; "
+ " jne 1b"
+ : "+m" (*p), /* 0 */
+ "+A" (v) /* 1 */
+ : : "ebx", "ecx", "memory", "cc");
+}
+
+static __inline uint64_t
+atomic_swap_64_i586(volatile uint64_t *p, uint64_t v)
+{
+
+ __asm __volatile(
+ " movl %%eax,%%ebx ; "
+ " movl %%edx,%%ecx ; "
+ "1: "
+ " " MPLOCKED " "
+ " cmpxchg8b %0 ; "
+ " jne 1b"
+ : "+m" (*p), /* 0 */
+ "+A" (v) /* 1 */
+ : : "ebx", "ecx", "memory", "cc");
+ return (v);
+}
+
+static __inline int
+atomic_cmpset_64(volatile uint64_t *dst, uint64_t expect, uint64_t src)
+{
+
+ if ((cpu_feature & CPUID_CX8) == 0)
+ return (atomic_cmpset_64_i386(dst, expect, src));
+ else
+ return (atomic_cmpset_64_i586(dst, expect, src));
+}
+
+static __inline uint64_t
+atomic_load_acq_64(volatile uint64_t *p)
+{
+
+ if ((cpu_feature & CPUID_CX8) == 0)
+ return (atomic_load_acq_64_i386(p));
+ else
+ return (atomic_load_acq_64_i586(p));
+}
+
+static __inline void
+atomic_store_rel_64(volatile uint64_t *p, uint64_t v)
+{
+
+ if ((cpu_feature & CPUID_CX8) == 0)
+ atomic_store_rel_64_i386(p, v);
+ else
+ atomic_store_rel_64_i586(p, v);
+}
+
+static __inline uint64_t
+atomic_swap_64(volatile uint64_t *p, uint64_t v)
+{
+
+ if ((cpu_feature & CPUID_CX8) == 0)
+ return (atomic_swap_64_i386(p, v));
+ else
+ return (atomic_swap_64_i586(p, v));
+}
+
+#endif /* _KERNEL */
+
#endif /* KLD_MODULE || !__GNUCLIKE_ASM */
ATOMIC_ASM(set, char, "orb %b1,%0", "iq", v);
@@ -366,11 +527,6 @@ ATOMIC_STORE(long);
#ifndef WANT_FUNCTIONS
-#ifdef _KERNEL
-extern uint64_t (*atomic_load_acq_64)(volatile uint64_t *);
-extern void (*atomic_store_rel_64)(volatile uint64_t *, uint64_t);
-#endif
-
static __inline int
atomic_cmpset_long(volatile u_long *dst, u_long expect, u_long src)
{
@@ -386,43 +542,39 @@ atomic_fetchadd_long(volatile u_long *p, u_long v)
return (atomic_fetchadd_int((volatile u_int *)p, (u_int)v));
}
-/* Read the current value and store a zero in the destination. */
+static __inline int
+atomic_testandset_long(volatile u_long *p, u_int v)
+{
+
+ return (atomic_testandset_int((volatile u_int *)p, v));
+}
+
+/* Read the current value and store a new value in the destination. */
#ifdef __GNUCLIKE_ASM
static __inline u_int
-atomic_readandclear_int(volatile u_int *p)
+atomic_swap_int(volatile u_int *p, u_int v)
{
- u_int res;
- res = 0;
__asm __volatile(
" xchgl %1,%0 ; "
- "# atomic_readandclear_int"
- : "+r" (res), /* 0 */
+ "# atomic_swap_int"
+ : "+r" (v), /* 0 */
"+m" (*p)); /* 1 */
-
- return (res);
+ return (v);
}
static __inline u_long
-atomic_readandclear_long(volatile u_long *p)
+atomic_swap_long(volatile u_long *p, u_long v)
{
- u_long res;
- res = 0;
- __asm __volatile(
- " xchgl %1,%0 ; "
- "# atomic_readandclear_long"
- : "+r" (res), /* 0 */
- "+m" (*p)); /* 1 */
-
- return (res);
+ return (atomic_swap_int((volatile u_int *)p, (u_int)v));
}
#else /* !__GNUCLIKE_ASM */
-u_int atomic_readandclear_int(volatile u_int *p);
-u_long atomic_readandclear_long(volatile u_long *p);
+u_int atomic_swap_int(volatile u_int *p, u_int v);
+u_long atomic_swap_long(volatile u_long *p, u_long v);
#endif /* __GNUCLIKE_ASM */
@@ -466,6 +618,9 @@ u_long atomic_readandclear_long(volatile u_long *p);
#define atomic_cmpset_acq_long atomic_cmpset_long
#define atomic_cmpset_rel_long atomic_cmpset_long
+#define atomic_readandclear_int(p) atomic_swap_int(p, 0)
+#define atomic_readandclear_long(p) atomic_swap_long(p, 0)
+
/* Operations on 8-bit bytes. */
#define atomic_set_8 atomic_set_char
#define atomic_set_acq_8 atomic_set_acq_char
@@ -516,8 +671,10 @@ u_long atomic_readandclear_long(volatile u_long *p);
#define atomic_cmpset_32 atomic_cmpset_int
#define atomic_cmpset_acq_32 atomic_cmpset_acq_int
#define atomic_cmpset_rel_32 atomic_cmpset_rel_int
+#define atomic_swap_32 atomic_swap_int
#define atomic_readandclear_32 atomic_readandclear_int
#define atomic_fetchadd_32 atomic_fetchadd_int
+#define atomic_testandset_32 atomic_testandset_int
/* Operations on pointers. */
#define atomic_set_ptr(p, v) \
@@ -556,6 +713,8 @@ u_long atomic_readandclear_long(volatile u_long *p);
#define atomic_cmpset_rel_ptr(dst, old, new) \
atomic_cmpset_rel_int((volatile u_int *)(dst), (u_int)(old), \
(u_int)(new))
+#define atomic_swap_ptr(p, v) \
+ atomic_swap_int((volatile u_int *)(p), (u_int)(v))
#define atomic_readandclear_ptr(p) \
atomic_readandclear_int((volatile u_int *)(p))
diff --git a/sys/i386/include/pmap.h b/sys/i386/include/pmap.h
index 8c20e1b..94b63ca 100644
--- a/sys/i386/include/pmap.h
+++ b/sys/i386/include/pmap.h
@@ -326,98 +326,27 @@ pmap_kextract(vm_offset_t va)
#if defined(PAE) && !defined(XEN)
-#define pde_cmpset(pdep, old, new) \
- atomic_cmpset_64((pdep), (old), (new))
-
-static __inline pt_entry_t
-pte_load(pt_entry_t *ptep)
-{
- pt_entry_t r;
-
- __asm __volatile(
- "lock; cmpxchg8b %1"
- : "=A" (r)
- : "m" (*ptep), "a" (0), "d" (0), "b" (0), "c" (0));
- return (r);
-}
-
-static __inline pt_entry_t
-pte_load_store(pt_entry_t *ptep, pt_entry_t v)
-{
- pt_entry_t r;
-
- r = *ptep;
- __asm __volatile(
- "1:\n"
- "\tlock; cmpxchg8b %1\n"
- "\tjnz 1b"
- : "+A" (r)
- : "m" (*ptep), "b" ((uint32_t)v), "c" ((uint32_t)(v >> 32)));
- return (r);
-}
-
-/* XXXRU move to atomic.h? */
-static __inline int
-atomic_cmpset_64(volatile uint64_t *dst, uint64_t exp, uint64_t src)
-{
- int64_t res = exp;
-
- __asm __volatile (
- " lock ; "
- " cmpxchg8b %2 ; "
- " setz %%al ; "
- " movzbl %%al,%0 ; "
- "# atomic_cmpset_64"
- : "+A" (res), /* 0 (result) */
- "=m" (*dst) /* 1 */
- : "m" (*dst), /* 2 */
- "b" ((uint32_t)src),
- "c" ((uint32_t)(src >> 32)));
-
- return (res);
-}
-
-#define pte_load_clear(ptep) pte_load_store((ptep), (pt_entry_t)0ULL)
-
-#define pte_store(ptep, pte) pte_load_store((ptep), (pt_entry_t)pte)
+#define pde_cmpset(pdep, old, new) atomic_cmpset_64_i586(pdep, old, new)
+#define pte_load_store(ptep, pte) atomic_swap_64_i586(ptep, pte)
+#define pte_load_clear(ptep) atomic_swap_64_i586(ptep, 0)
+#define pte_store(ptep, pte) atomic_store_rel_64_i586(ptep, pte)
extern pt_entry_t pg_nx;
-#elif !defined(PAE) && !defined (XEN)
-
-#define pde_cmpset(pdep, old, new) \
- atomic_cmpset_int((pdep), (old), (new))
-
-static __inline pt_entry_t
-pte_load(pt_entry_t *ptep)
-{
- pt_entry_t r;
-
- r = *ptep;
- return (r);
-}
-
-static __inline pt_entry_t
-pte_load_store(pt_entry_t *ptep, pt_entry_t pte)
-{
- __asm volatile("xchgl %0, %1" : "+m" (*ptep), "+r" (pte));
- return (pte);
-}
-
-#define pte_load_clear(pte) atomic_readandclear_int(pte)
+#elif !defined(PAE) && !defined(XEN)
-static __inline void
-pte_store(pt_entry_t *ptep, pt_entry_t pte)
-{
-
- *ptep = pte;
-}
+#define pde_cmpset(pdep, old, new) atomic_cmpset_int(pdep, old, new)
+#define pte_load_store(ptep, pte) atomic_swap_int(ptep, pte)
+#define pte_load_clear(ptep) atomic_swap_int(ptep, 0)
+#define pte_store(ptep, pte) do { \
+ *(u_int *)(ptep) = (u_int)(pte); \
+} while (0)
#endif /* PAE */
-#define pte_clear(ptep) pte_store((ptep), (pt_entry_t)0ULL)
+#define pte_clear(ptep) pte_store(ptep, 0)
-#define pde_store(pdep, pde) pte_store((pdep), (pde))
+#define pde_store(pdep, pde) pte_store(pdep, pde)
#endif /* _KERNEL */
diff --git a/sys/net80211/ieee80211_freebsd.h b/sys/net80211/ieee80211_freebsd.h
index 34e66d0..711bac3 100644
--- a/sys/net80211/ieee80211_freebsd.h
+++ b/sys/net80211/ieee80211_freebsd.h
@@ -234,9 +234,22 @@ struct mbuf *ieee80211_getmgtframe(uint8_t **frm, int headroom, int pktlen);
#define M_FF M_PROTO6 /* fast frame */
#define M_TXCB M_PROTO7 /* do tx complete callback */
#define M_AMPDU_MPDU M_PROTO8 /* ok for A-MPDU aggregation */
+
+/*
+ * FreeBSD-HEAD from 1000046 retired M_*FRAG* flags and turned them
+ * into header flags instead. So, we use the new protocol-specific
+ * flags.
+ *
+ * Earlier FreeBSD versions overload M_FRAG, M_FIRSTFRAG and M_LASTFRAG.
+ *
+ * XXX TODO: rename these fields so there are no namespace clashes!
+ */
+#if __FreeBSD_version >= 1000046
#define M_FRAG M_PROTO9 /* frame fragmentation */
#define M_FIRSTFRAG M_PROTO10 /* first frame fragment */
#define M_LASTFRAG M_PROTO11 /* last frame fragment */
+#endif
+
#define M_80211_TX \
(M_ENCAP|M_EAPOL|M_PWR_SAV|M_MORE_DATA|M_FF|M_TXCB| \
M_AMPDU_MPDU|M_FRAG|M_FIRSTFRAG|M_LASTFRAG)
@@ -249,10 +262,18 @@ struct mbuf *ieee80211_getmgtframe(uint8_t **frm, int headroom, int pktlen);
#endif
#define M_80211_RX (M_AMPDU|M_WEP|M_AMPDU_MPDU)
+#if __FreeBSD_version >= 1000046
#define IEEE80211_MBUF_TX_FLAG_BITS \
M_FLAG_BITS \
"\15M_ENCAP\17M_EAPOL\20M_PWR_SAV\21M_MORE_DATA\22M_FF\23M_TXCB" \
"\24M_AMPDU_MPDU\25M_FRAG\26M_FIRSTFRAG\27M_LASTFRAG"
+#else
+/* There aren't any flag bits available for versions before this */
+/* XXX TODO: implement M_FLAG_BITS for this! */
+#define IEEE80211_MBUF_TX_FLAG_BITS \
+ "\15M_ENCAP\17M_EAPOL\20M_PWR_SAV\21M_MORE_DATA\22M_FF\23M_TXCB" \
+ "\24M_AMPDU_MPDU"
+#endif
#define IEEE80211_MBUF_RX_FLAG_BITS \
M_FLAG_BITS \
diff --git a/sys/net80211/ieee80211_hostap.c b/sys/net80211/ieee80211_hostap.c
index 5839e7d..93a9b27 100644
--- a/sys/net80211/ieee80211_hostap.c
+++ b/sys/net80211/ieee80211_hostap.c
@@ -355,8 +355,12 @@ hostap_deliver_data(struct ieee80211vap *vap,
struct ifnet *ifp = vap->iv_ifp;
/* clear driver/net80211 flags before passing up */
+#if __FreeBSD_version >= 1000046
m->m_flags &= ~(M_MCAST | M_BCAST);
m_clrprotoflags(m);
+#else
+ m->m_flags &= ~(M_80211_RX | M_MCAST | M_BCAST);
+#endif
KASSERT(vap->iv_opmode == IEEE80211_M_HOSTAP,
("gack, opmode %d", vap->iv_opmode));
diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c
index a32ef18..5e95646 100644
--- a/sys/net80211/ieee80211_input.c
+++ b/sys/net80211/ieee80211_input.c
@@ -251,7 +251,9 @@ ieee80211_deliver_data(struct ieee80211vap *vap,
/* clear driver/net80211 flags before passing up */
m->m_flags &= ~(M_MCAST | M_BCAST);
+#if __FreeBSD_version >= 1000046
m_clrprotoflags(m);
+#endif
/* NB: see hostap_deliver_data, this path doesn't handle hostap */
KASSERT(vap->iv_opmode != IEEE80211_M_HOSTAP, ("gack, hostap"));
diff --git a/sys/netinet/in_mcast.c b/sys/netinet/in_mcast.c
index 31f2fe1..8022c69 100644
--- a/sys/netinet/in_mcast.c
+++ b/sys/netinet/in_mcast.c
@@ -1648,6 +1648,8 @@ inp_get_source_filters(struct inpcb *inp, struct sockopt *sopt)
* has asked for, but we always tell userland how big the
* buffer really needs to be.
*/
+ if (msfr.msfr_nsrcs > in_mcast_maxsocksrc)
+ msfr.msfr_nsrcs = in_mcast_maxsocksrc;
tss = NULL;
if (msfr.msfr_srcs != NULL && msfr.msfr_nsrcs > 0) {
tss = malloc(sizeof(struct sockaddr_storage) * msfr.msfr_nsrcs,
diff --git a/sys/netinet6/in6_mcast.c b/sys/netinet6/in6_mcast.c
index ce23aa8..fca48b5 100644
--- a/sys/netinet6/in6_mcast.c
+++ b/sys/netinet6/in6_mcast.c
@@ -1625,6 +1625,8 @@ in6p_get_source_filters(struct inpcb *inp, struct sockopt *sopt)
* has asked for, but we always tell userland how big the
* buffer really needs to be.
*/
+ if (msfr.msfr_nsrcs > in6_mcast_maxsocksrc)
+ msfr.msfr_nsrcs = in6_mcast_maxsocksrc;
tss = NULL;
if (msfr.msfr_srcs != NULL && msfr.msfr_nsrcs > 0) {
tss = malloc(sizeof(struct sockaddr_storage) * msfr.msfr_nsrcs,
diff --git a/sys/powerpc/conf/GENERIC64 b/sys/powerpc/conf/GENERIC64
index 54e3a4e..4b82ad8 100644
--- a/sys/powerpc/conf/GENERIC64
+++ b/sys/powerpc/conf/GENERIC64
@@ -24,6 +24,7 @@ ident GENERIC
machine powerpc powerpc64
makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
+makeoptions WITH_CTF=1
# Platform support
options POWERMAC #NewWorld Apple PowerMacs
@@ -67,6 +68,8 @@ options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions
options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4)
options AUDIT # Security event auditing
options MAC # TrustedBSD MAC Framework
+options KDTRACE_HOOKS # Kernel DTrace hooks
+options DDB_CTF # Kernel ELF linker loads CTF data
options INCLUDE_CONFIG_FILE # Include this file in kernel
# Debugging support. Always need this:
diff --git a/sys/sys/param.h b/sys/sys/param.h
index d18cc15..e157354 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -58,7 +58,7 @@
* in the range 5 to 9.
*/
#undef __FreeBSD_version
-#define __FreeBSD_version 1000046 /* Master, propagated to newvers */
+#define __FreeBSD_version 1000047 /* Master, propagated to newvers */
/*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,
diff --git a/sys/sys/stat.h b/sys/sys/stat.h
index f430a9a..0f3284f 100644
--- a/sys/sys/stat.h
+++ b/sys/sys/stat.h
@@ -265,8 +265,26 @@ struct nstat {
#define UF_NODUMP 0x00000001 /* do not dump file */
#define UF_IMMUTABLE 0x00000002 /* file may not be changed */
#define UF_APPEND 0x00000004 /* writes to file may only append */
-#define UF_OPAQUE 0x00000008 /* directory is opaque wrt. union */
-#define UF_NOUNLINK 0x00000010 /* file may not be removed or renamed */
+#define UF_OPAQUE 0x00000008 /* directory is opaque wrt. union */
+#define UF_NOUNLINK 0x00000010 /* file may not be removed or renamed */
+/*
+ * These two bits are defined in MacOS X. They are not currently used in
+ * FreeBSD.
+ */
+#if 0
+#define UF_COMPRESSED 0x00000020 /* file is compressed */
+#define UF_TRACKED 0x00000040 /* renames and deletes are tracked */
+#endif
+
+#define UF_SYSTEM 0x00000080 /* Windows system file bit */
+#define UF_SPARSE 0x00000100 /* sparse file */
+#define UF_OFFLINE 0x00000200 /* file is offline */
+#define UF_REPARSE 0x00000400 /* Windows reparse point file bit */
+#define UF_ARCHIVE 0x00000800 /* file needs to be archived */
+#define UF_READONLY 0x00001000 /* Windows readonly file bit */
+/* This is the same as the MacOS X definition of UF_HIDDEN. */
+#define UF_HIDDEN 0x00008000 /* file is hidden */
+
/*
* Super-user changeable flags.
*/
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index 729e967..56e24a3 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -528,9 +528,11 @@ ufs_setattr(ap)
return (EINVAL);
}
if (vap->va_flags != VNOVAL) {
- if ((vap->va_flags & ~(UF_NODUMP | UF_IMMUTABLE | UF_APPEND |
- UF_OPAQUE | UF_NOUNLINK | SF_ARCHIVED | SF_IMMUTABLE |
- SF_APPEND | SF_NOUNLINK | SF_SNAPSHOT)) != 0)
+ if ((vap->va_flags & ~(SF_APPEND | SF_ARCHIVED | SF_IMMUTABLE |
+ SF_NOUNLINK | SF_SNAPSHOT | UF_APPEND | UF_ARCHIVE |
+ UF_HIDDEN | UF_IMMUTABLE | UF_NODUMP | UF_NOUNLINK |
+ UF_OFFLINE | UF_OPAQUE | UF_READONLY | UF_REPARSE |
+ UF_SPARSE | UF_SYSTEM)) != 0)
return (EOPNOTSUPP);
if (vp->v_mount->mnt_flag & MNT_RDONLY)
return (EROFS);
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c
index 472ae78..5660b56 100644
--- a/sys/vm/vm_pageout.c
+++ b/sys/vm/vm_pageout.c
@@ -1333,25 +1333,6 @@ relock_queues:
m = next;
continue;
}
- object = m->object;
- if (!VM_OBJECT_TRYWLOCK(object) &&
- !vm_pageout_fallback_object_lock(m, &next)) {
- VM_OBJECT_WUNLOCK(object);
- vm_page_unlock(m);
- m = next;
- continue;
- }
-
- /*
- * Don't deactivate pages that are busy.
- */
- if (vm_page_busied(m) || m->hold_count != 0) {
- vm_page_unlock(m);
- VM_OBJECT_WUNLOCK(object);
- vm_page_requeue_locked(m);
- m = next;
- continue;
- }
/*
* The count for pagedaemon pages is done after checking the
@@ -1367,7 +1348,15 @@ relock_queues:
vm_page_aflag_clear(m, PGA_REFERENCED);
act_delta += 1;
}
- if (object->ref_count != 0)
+ /*
+ * Unlocked object ref count check. Two races are possible.
+ * 1) The ref was transitioning to zero and we saw non-zero,
+ * the pmap bits will be checked unnecessarily.
+ * 2) The ref was transitioning to one and we saw zero.
+ * The page lock prevents a new reference to this page so
+ * we need not check the reference bits.
+ */
+ if (m->object->ref_count != 0)
act_delta += pmap_ts_referenced(m);
/*
@@ -1387,9 +1376,6 @@ relock_queues:
* queue depending on usage.
*/
if (act_delta == 0) {
- KASSERT(object->ref_count != 0 ||
- !pmap_page_is_mapped(m),
- ("vm_pageout_scan: page %p is mapped", m));
/* Dequeue to avoid later lock recursion. */
vm_page_dequeue_locked(m);
vm_page_deactivate(m);
@@ -1397,7 +1383,6 @@ relock_queues:
} else
vm_page_requeue_locked(m);
vm_page_unlock(m);
- VM_OBJECT_WUNLOCK(object);
m = next;
}
vm_pagequeue_unlock(pq);
OpenPOWER on IntegriCloud