Browse Source

Merge branch 'freebsd/current/master' into hardened/current/master

* freebsd/current/master:
  Use calloc().
  Remove redundant check and wrong fix: fat.c checks already take care about cluster chains.
  periodic: replace "tty" with "test -t 0"
  Add an entry to RELNOTES for r351201.
  Add a vop_stdioctl() that performs a trivial FIOSEEKDATA/FIOSEEKHOLE.
  Allocate all per-cpu datastructures in domain correct memory.
hardened/current/master
Oliver Pinter + 9 months ago
parent
commit
9c68717005
8 changed files with 131 additions and 44 deletions
  1. +9
    -0
      RELNOTES
  2. +3
    -19
      sbin/fsck_msdosfs/dir.c
  3. +12
    -12
      sbin/fsck_msdosfs/fat.c
  4. +56
    -11
      sys/amd64/amd64/mp_machdep.c
  5. +11
    -0
      sys/dev/acpica/acpi_pxm.c
  6. +1
    -0
      sys/dev/acpica/acpivar.h
  7. +38
    -1
      sys/kern/vfs_default.c
  8. +1
    -1
      usr.sbin/periodic/periodic.sh

+ 9
- 0
RELNOTES View File

@@ -10,6 +10,15 @@ newline. Entries should be separated by a newline.

Changes to this file should not be MFCed.

r351201:
Add a vop_stdioctl() call, so that file systems that do not support
holes will have a trivial implementation of lseek(SEEK_DATA/SEEK_HOLE).
The algorithm appears to be compatible with the POSIX draft and
the implementation in Linux for the case of a file system that
does not support holes. Prior to this patch, lseek(2) would reply
-1 with errno set to ENOTTY for SEEK_DATA/SEEK_HOLE on files in
file systems that do not support holes.

r350665:
The fuse driver has been renamed to fusefs(5) and been substantially
rewritten. The new driver includes many bug fixes and performance

+ 3
- 19
sbin/fsck_msdosfs/dir.c View File

@@ -220,7 +220,6 @@ int
resetDosDirSection(struct bootblock *boot, struct fatEntry *fat)
{
int b1, b2;
cl_t cl;
int ret = FSOK;
size_t len;

@@ -253,24 +252,9 @@ resetDosDirSection(struct bootblock *boot, struct fatEntry *fat)
boot->bpbRootClust);
return FSFATAL;
}
cl = fat[boot->bpbRootClust].next;
if (cl < CLUST_FIRST
|| (cl >= CLUST_RSRVD && cl< CLUST_EOFS)
|| fat[boot->bpbRootClust].head != boot->bpbRootClust) {
if (cl == CLUST_FREE)
pwarn("Root directory starts with free cluster\n");
else if (cl >= CLUST_RSRVD)
pwarn("Root directory starts with cluster marked %s\n",
rsrvdcltype(cl));
else {
pfatal("Root directory doesn't start a cluster chain");
return FSFATAL;
}
if (ask(1, "Fix")) {
fat[boot->bpbRootClust].next = CLUST_FREE;
ret = FSFATMOD;
} else
ret = FSFATAL;
if (fat[boot->bpbRootClust].head != boot->bpbRootClust) {
pfatal("Root directory doesn't start a cluster chain");
return FSFATAL;
}

fat[boot->bpbRootClust].flags |= FAT_USED;

+ 12
- 12
sbin/fsck_msdosfs/fat.c View File

@@ -54,10 +54,10 @@ static int _readfat(int, struct bootblock *, u_int, u_char **);
* 31...... ........ ........ .......0
* rrrr1111 11111111 11111111 mmmmmmmm FAT32 entry 0
* rrrrsh11 11111111 11111111 11111xxx FAT32 entry 1
*
*
* 11111111 mmmmmmmm FAT16 entry 0
* sh111111 11111xxx FAT16 entry 1
*
*
* r = reserved
* m = BPB media ID byte
* s = clean flag (1 = dismounted; 0 = still mounted)
@@ -166,11 +166,11 @@ static int
_readfat(int fs, struct bootblock *boot, u_int no, u_char **buffer)
{
off_t off;
size_t len;

*buffer = malloc(len = boot->FATsecs * boot->bpbBytesPerSec);
*buffer = calloc(boot->FATsecs, boot->bpbBytesPerSec);
if (*buffer == NULL) {
perr("No space for FAT sectors (%zu)", len);
perr("No space for FAT sectors (%zu)",
(size_t)boot->FATsecs);
return 0;
}

@@ -205,20 +205,19 @@ readfat(int fs, struct bootblock *boot, u_int no, struct fatEntry **fp)
u_char *buffer, *p;
cl_t cl;
int ret = FSOK;
size_t len;

boot->NumFree = boot->NumBad = 0;

if (!_readfat(fs, boot, no, &buffer))
return FSFATAL;

fat = malloc(len = boot->NumClusters * sizeof(struct fatEntry));
fat = calloc(boot->NumClusters, sizeof(struct fatEntry));
if (fat == NULL) {
perr("No space for FAT clusters (%zu)", len);
perr("No space for FAT clusters (%zu)",
(size_t)boot->NumClusters);
free(buffer);
return FSFATAL;
}
(void)memset(fat, 0, len);

if (buffer[0] != boot->bpbMedia
|| buffer[1] != 0xff || buffer[2] != 0xff
@@ -566,12 +565,13 @@ writefat(int fs, struct bootblock *boot, struct fatEntry *fat, int correct_fat)
off_t off;
int ret = FSOK;

buffer = malloc(fatsz = boot->FATsecs * boot->bpbBytesPerSec);
fatsz = boot->FATsecs * boot->bpbBytesPerSec;
buffer = calloc(boot->FATsecs, boot->bpbBytesPerSec);
if (buffer == NULL) {
perr("No space for FAT sectors (%zu)", fatsz);
perr("No space for FAT sectors (%zu)",
(size_t)boot->FATsecs);
return FSFATAL;
}
memset(buffer, 0, fatsz);
boot->NumFree = 0;
p = buffer;
if (correct_fat) {

+ 56
- 11
sys/amd64/amd64/mp_machdep.c View File

@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/cpuset.h>
#include <sys/domainset.h>
#ifdef GPROF
#include <sys/gmon.h>
#endif
@@ -59,6 +60,8 @@ __FBSDID("$FreeBSD$");
#include <vm/pmap.h>
#include <vm/vm_kern.h>
#include <vm/vm_extern.h>
#include <vm/vm_page.h>
#include <vm/vm_phys.h>

#include <x86/apicreg.h>
#include <machine/clock.h>
@@ -75,6 +78,9 @@ __FBSDID("$FreeBSD$");
#include <machine/cpu.h>
#include <x86/init.h>

#include <contrib/dev/acpica/include/acpi.h>
#include <dev/acpica/acpivar.h>

#define WARMBOOT_TARGET 0
#define WARMBOOT_OFF (KERNBASE + 0x0467)
#define WARMBOOT_SEG (KERNBASE + 0x0469)
@@ -384,6 +390,25 @@ init_secondary(void)
* local functions and data
*/

#ifdef NUMA
static void
mp_realloc_pcpu(int cpuid, int domain)
{
vm_page_t m;
vm_offset_t oa, na;

oa = (vm_offset_t)&__pcpu[cpuid];
if (_vm_phys_domain(pmap_kextract(oa)) == domain)
return;
m = vm_page_alloc_domain(NULL, 0, domain,
VM_ALLOC_NORMAL | VM_ALLOC_NOOBJ | VM_ALLOC_ZERO);
na = PHYS_TO_DMAP(VM_PAGE_TO_PHYS(m));
pagecopy((void *)oa, (void *)na);
pmap_enter(kernel_pmap, oa, m, VM_PROT_READ | VM_PROT_WRITE, 0, 0);
/* XXX old pcpu page leaked. */
}
#endif

/*
* start each AP in our list
*/
@@ -392,7 +417,7 @@ native_start_all_aps(void)
{
u_int64_t *pt4, *pt3, *pt2;
u_int32_t mpbioswarmvec;
int apic_id, cpu, i;
int apic_id, cpu, domain, i;
u_char mpbiosreason;

mtx_init(&ap_boot_mtx, "ap boot", NULL, MTX_SPIN);
@@ -431,21 +456,41 @@ native_start_all_aps(void)
outb(CMOS_REG, BIOS_RESET);
outb(CMOS_DATA, BIOS_WARM); /* 'warm-start' */

/* Relocate pcpu areas to the correct domain. */
#ifdef NUMA
if (vm_ndomains > 1)
for (cpu = 1; cpu < mp_ncpus; cpu++) {
apic_id = cpu_apic_ids[cpu];
domain = acpi_pxm_get_cpu_locality(apic_id);
mp_realloc_pcpu(cpu, domain);
}
#endif

/* start each AP */
domain = 0;
for (cpu = 1; cpu < mp_ncpus; cpu++) {
apic_id = cpu_apic_ids[cpu];

#ifdef NUMA
if (vm_ndomains > 1)
domain = acpi_pxm_get_cpu_locality(apic_id);
#endif
/* allocate and set up an idle stack data page */
bootstacks[cpu] = (void *)kmem_malloc(kstack_pages * PAGE_SIZE,
bootstacks[cpu] = (void *)kmem_malloc_domainset(
DOMAINSET_FIXED(domain), kstack_pages * PAGE_SIZE,
M_WAITOK | M_ZERO);
doublefault_stack = (char *)kmem_malloc(PAGE_SIZE, M_WAITOK |
M_ZERO);
mce_stack = (char *)kmem_malloc(PAGE_SIZE, M_WAITOK | M_ZERO);
nmi_stack = (char *)kmem_malloc(PAGE_SIZE, M_WAITOK | M_ZERO);
dbg_stack = (char *)kmem_malloc(PAGE_SIZE, M_WAITOK | M_ZERO);
dpcpu = (void *)kmem_malloc(DPCPU_SIZE, M_WAITOK | M_ZERO);

bootSTK = (char *)bootstacks[cpu] + kstack_pages * PAGE_SIZE - 8;
doublefault_stack = (char *)kmem_malloc_domainset(
DOMAINSET_FIXED(domain), PAGE_SIZE, M_WAITOK | M_ZERO);
mce_stack = (char *)kmem_malloc_domainset(
DOMAINSET_FIXED(domain), PAGE_SIZE, M_WAITOK | M_ZERO);
nmi_stack = (char *)kmem_malloc_domainset(
DOMAINSET_FIXED(domain), PAGE_SIZE, M_WAITOK | M_ZERO);
dbg_stack = (char *)kmem_malloc_domainset(
DOMAINSET_FIXED(domain), PAGE_SIZE, M_WAITOK | M_ZERO);
dpcpu = (void *)kmem_malloc_domainset(DOMAINSET_FIXED(domain),
DPCPU_SIZE, M_WAITOK | M_ZERO);

bootSTK = (char *)bootstacks[cpu] +
kstack_pages * PAGE_SIZE - 8;
bootAP = cpu;

/* attempt to start the Application Processor */

+ 11
- 0
sys/dev/acpica/acpi_pxm.c View File

@@ -653,6 +653,17 @@ acpi_pxm_set_cpu_locality(void)
}
}

int
acpi_pxm_get_cpu_locality(int apic_id)
{
struct cpu_info *cpu;

cpu = cpu_find(apic_id);
if (cpu == NULL)
panic("SRAT: CPU with ID %u is not known", apic_id);
return (cpu->domain);
}

/*
* Free data structures allocated during acpi_pxm_init.
*/

+ 1
- 0
sys/dev/acpica/acpivar.h View File

@@ -532,6 +532,7 @@ int acpi_pxm_init(int ncpus, vm_paddr_t maxphys);
void acpi_pxm_parse_tables(void);
void acpi_pxm_set_mem_locality(void);
void acpi_pxm_set_cpu_locality(void);
int acpi_pxm_get_cpu_locality(int apic_id);
void acpi_pxm_free(void);

/*

+ 38
- 1
sys/kern/vfs_default.c View File

@@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
#include <sys/buf.h>
#include <sys/conf.h>
#include <sys/event.h>
#include <sys/filio.h>
#include <sys/kernel.h>
#include <sys/limits.h>
#include <sys/lock.h>
@@ -86,6 +87,7 @@ static int vop_stdadd_writecount(struct vop_add_writecount_args *ap);
static int vop_stdcopy_file_range(struct vop_copy_file_range_args *ap);
static int vop_stdfdatasync(struct vop_fdatasync_args *ap);
static int vop_stdgetpages_async(struct vop_getpages_async_args *ap);
static int vop_stdioctl(struct vop_ioctl_args *ap);

/*
* This vnode table stores what we want to do if the filesystem doesn't
@@ -118,7 +120,7 @@ struct vop_vector default_vnodeops = {
.vop_getpages_async = vop_stdgetpages_async,
.vop_getwritemount = vop_stdgetwritemount,
.vop_inactive = VOP_NULL,
.vop_ioctl = VOP_ENOTTY,
.vop_ioctl = vop_stdioctl,
.vop_kqfilter = vop_stdkqfilter,
.vop_islocked = vop_stdislocked,
.vop_lock1 = vop_stdlock,
@@ -1155,6 +1157,41 @@ vop_stdadd_writecount(struct vop_add_writecount_args *ap)
return (error);
}

static int
vop_stdioctl(struct vop_ioctl_args *ap)
{
struct vnode *vp;
struct vattr va;
off_t *offp;
int error;

switch (ap->a_command) {
case FIOSEEKDATA:
case FIOSEEKHOLE:
vp = ap->a_vp;
error = vn_lock(vp, LK_SHARED);
if (error != 0)
return (EBADF);
if (vp->v_type == VREG)
error = VOP_GETATTR(vp, &va, ap->a_cred);
else
error = ENOTTY;
if (error == 0) {
offp = ap->a_data;
if (*offp < 0 || *offp >= va.va_size)
error = ENXIO;
else if (ap->a_command == FIOSEEKHOLE)
*offp = va.va_size;
}
VOP_UNLOCK(vp, 0);
break;
default:
error = ENOTTY;
break;
}
return (error);
}

/*
* vfs default ops
* used to fill the vfs function table to get reasonable default return values.

+ 1
- 1
usr.sbin/periodic/periodic.sh View File

@@ -84,7 +84,7 @@ else
# remove the file.
remove_periodic_anticongestion_file=no
fi
if tty > /dev/null 2>&1; then
if [ -t 0 ]; then
export PERIODIC_IS_INTERACTIVE=1
fi
tmp_output=`mktemp ${TMPDIR:-/tmp}/periodic.XXXXXXXXXX`

Loading…
Cancel
Save