Changeset View
Standalone View
sys/kern/uipc_shm.c
Show First 20 Lines • Show All 109 Lines • ▼ Show 20 Lines | |||||
static struct sx shm_dict_lock; | static struct sx shm_dict_lock; | ||||
static struct mtx shm_timestamp_lock; | static struct mtx shm_timestamp_lock; | ||||
static u_long shm_hash; | static u_long shm_hash; | ||||
static struct unrhdr64 shm_ino_unr; | static struct unrhdr64 shm_ino_unr; | ||||
static dev_t shm_dev_ino; | static dev_t shm_dev_ino; | ||||
#define SHM_HASH(fnv) (&shm_dictionary[(fnv) & shm_hash]) | #define SHM_HASH(fnv) (&shm_dictionary[(fnv) & shm_hash]) | ||||
#define SHM_SEAL_XLOCK(shmfd) sx_xlock(&(shmfd)->shm_seal_sx) | |||||
#define SHM_SEAL_XUNLOCK(shmfd) sx_xunlock(&(shmfd)->shm_seal_sx) | |||||
#define SHM_SEAL_SLOCK(shmfd) sx_slock(&(shmfd)->shm_seal_sx) | |||||
#define SHM_SEAL_SUNLOCK(shmfd) sx_sunlock(&(shmfd)->shm_seal_sx) | |||||
#define SHM_SEAL_UNLOCK(shmfd) sx_unlock(&(shmfd)->shm_seal_sx) | |||||
#define SHM_SEAL_DOWNGRADE(shmfd) sx_downgrade(&(shmfd)->shm_seal_sx) | |||||
#define SHM_SEAL_ASSERT_LOCKED(shmfd) \ | |||||
sx_assert(&(shmfd)->shm_seal_sx, SA_LOCKED) | |||||
static void shm_init(void *arg); | static void shm_init(void *arg); | ||||
static void shm_insert(char *path, Fnv32_t fnv, struct shmfd *shmfd); | static void shm_insert(char *path, Fnv32_t fnv, struct shmfd *shmfd); | ||||
static struct shmfd *shm_lookup(char *path, Fnv32_t fnv); | static struct shmfd *shm_lookup(char *path, Fnv32_t fnv); | ||||
static int shm_remove(char *path, Fnv32_t fnv, struct ucred *ucred); | static int shm_remove(char *path, Fnv32_t fnv, struct ucred *ucred); | ||||
static fo_rdwr_t shm_read; | static fo_rdwr_t shm_read; | ||||
static fo_rdwr_t shm_write; | static fo_rdwr_t shm_write; | ||||
static fo_truncate_t shm_truncate; | static fo_truncate_t shm_truncate; | ||||
static fo_ioctl_t shm_ioctl; | static fo_ioctl_t shm_ioctl; | ||||
static fo_stat_t shm_stat; | static fo_stat_t shm_stat; | ||||
static fo_close_t shm_close; | static fo_close_t shm_close; | ||||
static fo_chmod_t shm_chmod; | static fo_chmod_t shm_chmod; | ||||
static fo_chown_t shm_chown; | static fo_chown_t shm_chown; | ||||
static fo_seek_t shm_seek; | static fo_seek_t shm_seek; | ||||
static fo_fill_kinfo_t shm_fill_kinfo; | static fo_fill_kinfo_t shm_fill_kinfo; | ||||
static fo_mmap_t shm_mmap; | static fo_mmap_t shm_mmap; | ||||
static fo_get_seals_t shm_get_seals; | |||||
static fo_add_seals_t shm_add_seals; | |||||
/* File descriptor operations. */ | /* File descriptor operations. */ | ||||
struct fileops shm_ops = { | struct fileops shm_ops = { | ||||
.fo_read = shm_read, | .fo_read = shm_read, | ||||
.fo_write = shm_write, | .fo_write = shm_write, | ||||
.fo_truncate = shm_truncate, | .fo_truncate = shm_truncate, | ||||
.fo_ioctl = shm_ioctl, | .fo_ioctl = shm_ioctl, | ||||
.fo_poll = invfo_poll, | .fo_poll = invfo_poll, | ||||
.fo_kqfilter = invfo_kqfilter, | .fo_kqfilter = invfo_kqfilter, | ||||
.fo_stat = shm_stat, | .fo_stat = shm_stat, | ||||
.fo_close = shm_close, | .fo_close = shm_close, | ||||
.fo_chmod = shm_chmod, | .fo_chmod = shm_chmod, | ||||
.fo_chown = shm_chown, | .fo_chown = shm_chown, | ||||
.fo_sendfile = vn_sendfile, | .fo_sendfile = vn_sendfile, | ||||
.fo_seek = shm_seek, | .fo_seek = shm_seek, | ||||
.fo_fill_kinfo = shm_fill_kinfo, | .fo_fill_kinfo = shm_fill_kinfo, | ||||
.fo_mmap = shm_mmap, | .fo_mmap = shm_mmap, | ||||
.fo_get_seals = shm_get_seals, | |||||
.fo_add_seals = shm_add_seals, | |||||
.fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE | .fo_flags = DFLAG_PASSABLE | DFLAG_SEEKABLE | ||||
}; | }; | ||||
FEATURE(posix_shm, "POSIX shared memory"); | FEATURE(posix_shm, "POSIX shared memory"); | ||||
static int | static int | ||||
uiomove_object_page(vm_object_t obj, size_t len, struct uio *uio) | uiomove_object_page(vm_object_t obj, size_t len, struct uio *uio) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 159 Lines • ▼ Show 20 Lines | shm_write(struct file *fp, struct uio *uio, struct ucred *active_cred, | ||||
int error; | int error; | ||||
shmfd = fp->f_data; | shmfd = fp->f_data; | ||||
#ifdef MAC | #ifdef MAC | ||||
error = mac_posixshm_check_write(active_cred, fp->f_cred, shmfd); | error = mac_posixshm_check_write(active_cred, fp->f_cred, shmfd); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
#endif | #endif | ||||
SHM_SEAL_SLOCK(shmfd); | |||||
if ((shmfd->shm_seals & F_SEAL_WRITE) != 0) { | |||||
SHM_SEAL_SUNLOCK(shmfd); | |||||
return (EPERM); | |||||
} | |||||
foffset_lock_uio(fp, uio, flags); | foffset_lock_uio(fp, uio, flags); | ||||
if ((flags & FOF_OFFSET) == 0) { | if ((flags & FOF_OFFSET) == 0) { | ||||
rl_cookie = rangelock_wlock(&shmfd->shm_rl, 0, OFF_MAX, | rl_cookie = rangelock_wlock(&shmfd->shm_rl, 0, OFF_MAX, | ||||
&shmfd->shm_mtx); | &shmfd->shm_mtx); | ||||
} else { | } else { | ||||
rl_cookie = rangelock_wlock(&shmfd->shm_rl, uio->uio_offset, | rl_cookie = rangelock_wlock(&shmfd->shm_rl, uio->uio_offset, | ||||
uio->uio_offset + uio->uio_resid, &shmfd->shm_mtx); | uio->uio_offset + uio->uio_resid, &shmfd->shm_mtx); | ||||
} | } | ||||
error = uiomove_object(shmfd->shm_object, shmfd->shm_size, uio); | error = uiomove_object(shmfd->shm_object, shmfd->shm_size, uio); | ||||
rangelock_unlock(&shmfd->shm_rl, rl_cookie, &shmfd->shm_mtx); | rangelock_unlock(&shmfd->shm_rl, rl_cookie, &shmfd->shm_mtx); | ||||
foffset_unlock_uio(fp, uio, flags); | foffset_unlock_uio(fp, uio, flags); | ||||
SHM_SEAL_SUNLOCK(shmfd); | |||||
return (error); | return (error); | ||||
} | } | ||||
static int | static int | ||||
shm_truncate(struct file *fp, off_t length, struct ucred *active_cred, | shm_truncate(struct file *fp, off_t length, struct ucred *active_cred, | ||||
struct thread *td) | struct thread *td) | ||||
{ | { | ||||
struct shmfd *shmfd; | struct shmfd *shmfd; | ||||
▲ Show 20 Lines • Show All 76 Lines • ▼ Show 20 Lines | shm_close(struct file *fp, struct thread *td) | ||||
shmfd = fp->f_data; | shmfd = fp->f_data; | ||||
fp->f_data = NULL; | fp->f_data = NULL; | ||||
shm_drop(shmfd); | shm_drop(shmfd); | ||||
return (0); | return (0); | ||||
} | } | ||||
int | static int | ||||
shm_dotruncate(struct shmfd *shmfd, off_t length) | shm_dotruncate_locked(struct shmfd *shmfd, off_t length) | ||||
{ | { | ||||
vm_object_t object; | vm_object_t object; | ||||
vm_page_t m; | vm_page_t m; | ||||
vm_pindex_t idx, nobjsize; | vm_pindex_t idx, nobjsize; | ||||
vm_ooffset_t delta; | vm_ooffset_t delta; | ||||
int base, rv; | int base, rv; | ||||
KASSERT(length >= 0, ("shm_dotruncate: length < 0")); | KASSERT(length >= 0, ("shm_dotruncate: length < 0")); | ||||
SHM_SEAL_ASSERT_LOCKED(shmfd); | |||||
kib: I do not think this blank line is useful. | |||||
object = shmfd->shm_object; | object = shmfd->shm_object; | ||||
VM_OBJECT_WLOCK(object); | VM_OBJECT_WLOCK(object); | ||||
if (length == shmfd->shm_size) { | if (length == shmfd->shm_size) { | ||||
VM_OBJECT_WUNLOCK(object); | VM_OBJECT_WUNLOCK(object); | ||||
return (0); | return (0); | ||||
} | } | ||||
nobjsize = OFF_TO_IDX(length + PAGE_MASK); | nobjsize = OFF_TO_IDX(length + PAGE_MASK); | ||||
/* Are we shrinking? If so, trim the end. */ | /* Are we shrinking? If so, trim the end. */ | ||||
if (length < shmfd->shm_size) { | if (length < shmfd->shm_size) { | ||||
if ((shmfd->shm_seals & F_SEAL_SHRINK) != 0) { | |||||
VM_OBJECT_WUNLOCK(object); | |||||
return (EPERM); | |||||
} | |||||
/* | /* | ||||
* Disallow any requests to shrink the size if this | * Disallow any requests to shrink the size if this | ||||
* object is mapped into the kernel. | * object is mapped into the kernel. | ||||
*/ | */ | ||||
if (shmfd->shm_kmappings > 0) { | if (shmfd->shm_kmappings > 0) { | ||||
VM_OBJECT_WUNLOCK(object); | VM_OBJECT_WUNLOCK(object); | ||||
return (EBUSY); | return (EBUSY); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | retry: | ||||
/* Toss pages from swap. */ | /* Toss pages from swap. */ | ||||
if (object->type == OBJT_SWAP) | if (object->type == OBJT_SWAP) | ||||
swap_pager_freespace(object, nobjsize, delta); | swap_pager_freespace(object, nobjsize, delta); | ||||
/* Free the swap accounted for shm */ | /* Free the swap accounted for shm */ | ||||
swap_release_by_cred(delta, object->cred); | swap_release_by_cred(delta, object->cred); | ||||
object->charge -= delta; | object->charge -= delta; | ||||
} else { | } else { | ||||
if ((shmfd->shm_seals & F_SEAL_GROW) != 0) { | |||||
VM_OBJECT_WUNLOCK(object); | |||||
return (EPERM); | |||||
} | |||||
/* Try to reserve additional swap space. */ | /* Try to reserve additional swap space. */ | ||||
delta = IDX_TO_OFF(nobjsize - object->size); | delta = IDX_TO_OFF(nobjsize - object->size); | ||||
if (!swap_reserve_by_cred(delta, object->cred)) { | if (!swap_reserve_by_cred(delta, object->cred)) { | ||||
VM_OBJECT_WUNLOCK(object); | VM_OBJECT_WUNLOCK(object); | ||||
return (ENOMEM); | return (ENOMEM); | ||||
} | } | ||||
object->charge += delta; | object->charge += delta; | ||||
} | } | ||||
shmfd->shm_size = length; | shmfd->shm_size = length; | ||||
mtx_lock(&shm_timestamp_lock); | mtx_lock(&shm_timestamp_lock); | ||||
vfs_timestamp(&shmfd->shm_ctime); | vfs_timestamp(&shmfd->shm_ctime); | ||||
shmfd->shm_mtime = shmfd->shm_ctime; | shmfd->shm_mtime = shmfd->shm_ctime; | ||||
mtx_unlock(&shm_timestamp_lock); | mtx_unlock(&shm_timestamp_lock); | ||||
object->size = nobjsize; | object->size = nobjsize; | ||||
VM_OBJECT_WUNLOCK(object); | VM_OBJECT_WUNLOCK(object); | ||||
return (0); | return (0); | ||||
} | } | ||||
int | |||||
shm_dotruncate(struct shmfd *shmfd, off_t length) | |||||
{ | |||||
int rv; | |||||
kibUnsubmitted Done Inline ActionsTraditionally rv denotes Mach error. Please use error there. kib: Traditionally `rv` denotes Mach error. Please use `error` there. | |||||
SHM_SEAL_SLOCK(shmfd); | |||||
kibUnsubmitted Done Inline ActionsCan you move object locking there as well ? kib: Can you move object locking there as well ? | |||||
rv = shm_dotruncate_locked(shmfd, length); | |||||
SHM_SEAL_SUNLOCK(shmfd); | |||||
return (rv); | |||||
} | |||||
/* | /* | ||||
* shmfd object management including creation and reference counting | * shmfd object management including creation and reference counting | ||||
* routines. | * routines. | ||||
*/ | */ | ||||
struct shmfd * | struct shmfd * | ||||
shm_alloc(struct ucred *ucred, mode_t mode) | shm_alloc(struct ucred *ucred, mode_t mode) | ||||
{ | { | ||||
struct shmfd *shmfd; | struct shmfd *shmfd; | ||||
Show All 12 Lines | shm_alloc(struct ucred *ucred, mode_t mode) | ||||
vm_object_set_flag(shmfd->shm_object, OBJ_COLORED | OBJ_NOSPLIT); | vm_object_set_flag(shmfd->shm_object, OBJ_COLORED | OBJ_NOSPLIT); | ||||
VM_OBJECT_WUNLOCK(shmfd->shm_object); | VM_OBJECT_WUNLOCK(shmfd->shm_object); | ||||
vfs_timestamp(&shmfd->shm_birthtime); | vfs_timestamp(&shmfd->shm_birthtime); | ||||
shmfd->shm_atime = shmfd->shm_mtime = shmfd->shm_ctime = | shmfd->shm_atime = shmfd->shm_mtime = shmfd->shm_ctime = | ||||
shmfd->shm_birthtime; | shmfd->shm_birthtime; | ||||
shmfd->shm_ino = alloc_unr64(&shm_ino_unr); | shmfd->shm_ino = alloc_unr64(&shm_ino_unr); | ||||
refcount_init(&shmfd->shm_refs, 1); | refcount_init(&shmfd->shm_refs, 1); | ||||
mtx_init(&shmfd->shm_mtx, "shmrl", NULL, MTX_DEF); | mtx_init(&shmfd->shm_mtx, "shmrl", NULL, MTX_DEF); | ||||
sx_init(&shmfd->shm_seal_sx, "shmseal"); | |||||
rangelock_init(&shmfd->shm_rl); | rangelock_init(&shmfd->shm_rl); | ||||
#ifdef MAC | #ifdef MAC | ||||
mac_posixshm_init(shmfd); | mac_posixshm_init(shmfd); | ||||
mac_posixshm_create(ucred, shmfd); | mac_posixshm_create(ucred, shmfd); | ||||
#endif | #endif | ||||
return (shmfd); | return (shmfd); | ||||
} | } | ||||
Show All 10 Lines | |||||
shm_drop(struct shmfd *shmfd) | shm_drop(struct shmfd *shmfd) | ||||
{ | { | ||||
if (refcount_release(&shmfd->shm_refs)) { | if (refcount_release(&shmfd->shm_refs)) { | ||||
#ifdef MAC | #ifdef MAC | ||||
mac_posixshm_destroy(shmfd); | mac_posixshm_destroy(shmfd); | ||||
#endif | #endif | ||||
rangelock_destroy(&shmfd->shm_rl); | rangelock_destroy(&shmfd->shm_rl); | ||||
sx_destroy(&shmfd->shm_seal_sx); | |||||
mtx_destroy(&shmfd->shm_mtx); | mtx_destroy(&shmfd->shm_mtx); | ||||
vm_object_deallocate(shmfd->shm_object); | vm_object_deallocate(shmfd->shm_object); | ||||
free(shmfd, M_SHMFD); | free(shmfd, M_SHMFD); | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* Determine if the credentials have sufficient permissions for a | * Determine if the credentials have sufficient permissions for a | ||||
▲ Show 20 Lines • Show All 295 Lines • ▼ Show 20 Lines | shm_mmap(struct file *fp, vm_map_t map, vm_offset_t *addr, vm_size_t objsize, | ||||
struct shmfd *shmfd; | struct shmfd *shmfd; | ||||
vm_prot_t maxprot; | vm_prot_t maxprot; | ||||
int error; | int error; | ||||
bool writecnt; | bool writecnt; | ||||
shmfd = fp->f_data; | shmfd = fp->f_data; | ||||
maxprot = VM_PROT_NONE; | maxprot = VM_PROT_NONE; | ||||
SHM_SEAL_SLOCK(shmfd); | |||||
/* FREAD should always be set. */ | /* FREAD should always be set. */ | ||||
if ((fp->f_flag & FREAD) != 0) | if ((fp->f_flag & FREAD) != 0) | ||||
maxprot |= VM_PROT_EXECUTE | VM_PROT_READ; | maxprot |= VM_PROT_EXECUTE | VM_PROT_READ; | ||||
if ((fp->f_flag & FWRITE) != 0) | if ((fp->f_flag & FWRITE) != 0) | ||||
maxprot |= VM_PROT_WRITE; | maxprot |= VM_PROT_WRITE; | ||||
writecnt = (flags & MAP_SHARED) != 0 && (prot & VM_PROT_WRITE) != 0; | writecnt = (flags & MAP_SHARED) != 0 && (prot & VM_PROT_WRITE) != 0; | ||||
if (writecnt && (shmfd->shm_seals & F_SEAL_WRITE) != 0) { | |||||
SHM_SEAL_SUNLOCK(shmfd); | |||||
return (EPERM); | |||||
} | |||||
/* Don't permit shared writable mappings on read-only descriptors. */ | /* Don't permit shared writable mappings on read-only descriptors. */ | ||||
if (writecnt && (maxprot & VM_PROT_WRITE) == 0) | if (writecnt && (maxprot & VM_PROT_WRITE) == 0) { | ||||
SHM_SEAL_SUNLOCK(shmfd); | |||||
return (EACCES); | return (EACCES); | ||||
} | |||||
maxprot &= cap_maxprot; | maxprot &= cap_maxprot; | ||||
/* See comment in vn_mmap(). */ | /* See comment in vn_mmap(). */ | ||||
if ( | if ( | ||||
#ifdef _LP64 | #ifdef _LP64 | ||||
objsize > OFF_MAX || | objsize > OFF_MAX || | ||||
#endif | #endif | ||||
foff < 0 || foff > OFF_MAX - objsize) | foff < 0 || foff > OFF_MAX - objsize) { | ||||
SHM_SEAL_SUNLOCK(shmfd); | |||||
return (EINVAL); | return (EINVAL); | ||||
} | |||||
#ifdef MAC | #ifdef MAC | ||||
error = mac_posixshm_check_mmap(td->td_ucred, shmfd, prot, flags); | error = mac_posixshm_check_mmap(td->td_ucred, shmfd, prot, flags); | ||||
if (error != 0) | if (error != 0) { | ||||
SHM_SEAL_SUNLOCK(shmfd); | |||||
return (error); | return (error); | ||||
} | |||||
#endif | #endif | ||||
mtx_lock(&shm_timestamp_lock); | mtx_lock(&shm_timestamp_lock); | ||||
vfs_timestamp(&shmfd->shm_atime); | vfs_timestamp(&shmfd->shm_atime); | ||||
mtx_unlock(&shm_timestamp_lock); | mtx_unlock(&shm_timestamp_lock); | ||||
vm_object_reference(shmfd->shm_object); | vm_object_reference(shmfd->shm_object); | ||||
if (writecnt) | if (writecnt) | ||||
vm_pager_update_writecount(shmfd->shm_object, 0, objsize); | vm_pager_update_writecount(shmfd->shm_object, 0, objsize); | ||||
error = vm_mmap_object(map, addr, objsize, prot, maxprot, flags, | error = vm_mmap_object(map, addr, objsize, prot, maxprot, flags, | ||||
shmfd->shm_object, foff, writecnt, td); | shmfd->shm_object, foff, writecnt, td); | ||||
if (error != 0) { | if (error != 0) { | ||||
if (writecnt) | if (writecnt) | ||||
vm_pager_release_writecount(shmfd->shm_object, 0, | vm_pager_release_writecount(shmfd->shm_object, 0, | ||||
objsize); | objsize); | ||||
vm_object_deallocate(shmfd->shm_object); | vm_object_deallocate(shmfd->shm_object); | ||||
} | } | ||||
SHM_SEAL_SUNLOCK(shmfd); | |||||
return (error); | return (error); | ||||
} | } | ||||
static int | static int | ||||
shm_chmod(struct file *fp, mode_t mode, struct ucred *active_cred, | shm_chmod(struct file *fp, mode_t mode, struct ucred *active_cred, | ||||
struct thread *td) | struct thread *td) | ||||
{ | { | ||||
struct shmfd *shmfd; | struct shmfd *shmfd; | ||||
▲ Show 20 Lines • Show All 189 Lines • ▼ Show 20 Lines | shm_fill_kinfo(struct file *fp, struct kinfo_file *kif, | ||||
struct filedesc *fdp __unused) | struct filedesc *fdp __unused) | ||||
{ | { | ||||
int res; | int res; | ||||
sx_slock(&shm_dict_lock); | sx_slock(&shm_dict_lock); | ||||
res = shm_fill_kinfo_locked(fp->f_data, kif, false); | res = shm_fill_kinfo_locked(fp->f_data, kif, false); | ||||
sx_sunlock(&shm_dict_lock); | sx_sunlock(&shm_dict_lock); | ||||
return (res); | return (res); | ||||
} | |||||
static int | |||||
shm_add_seals(struct file *fp, int seals) | |||||
{ | |||||
struct shmfd *shmfd; | |||||
vm_ooffset_t writemappings; | |||||
int nseals; | |||||
shmfd = fp->f_data; | |||||
SHM_SEAL_XLOCK(shmfd); | |||||
/* Even already-set seals should result in EPERM. */ | |||||
if ((shmfd->shm_seals & F_SEAL_SEAL) != 0) { | |||||
SHM_SEAL_XUNLOCK(shmfd); | |||||
return (EPERM); | |||||
} | |||||
nseals = seals & ~shmfd->shm_seals; | |||||
if ((nseals & F_SEAL_WRITE) != 0) { | |||||
/* | |||||
* RLOCK because we're already protected from a writable mapping | |||||
* being added during this process by the shm_seals lock. | |||||
*/ | |||||
VM_OBJECT_RLOCK(shmfd->shm_object); | |||||
kibUnsubmitted Done Inline ActionsThis lock is only useful because reading of writemappings could be non-atomic on 32bit arches, right ? kib: This lock is only useful because reading of writemappings could be non-atomic on 32bit arches… | |||||
kevansAuthorUnsubmitted Done Inline ActionsThis was my theory at least, yeah. kevans: This was my theory at least, yeah. | |||||
writemappings = shmfd->shm_object->un_pager.swp.writemappings; | |||||
VM_OBJECT_RUNLOCK(shmfd->shm_object); | |||||
Done Inline ActionsI think you should note that we unmap i.e. decrement writemappings without taking a range lock, so the object lock there is to avoid torn reads on ILP32 arches. kib: I think you should note that we unmap i.e. decrement writemappings without taking a range lock… | |||||
/* kmappings are also writable */ | |||||
if (writemappings > 0) { | |||||
SHM_SEAL_XUNLOCK(shmfd); | |||||
return (EBUSY); | |||||
} | |||||
} | |||||
shmfd->shm_seals |= nseals; | |||||
SHM_SEAL_XUNLOCK(shmfd); | |||||
Not Done Inline ActionsDid you mean to also check shm_kmappings here? They are not counted in the object. markj: Did you mean to also check shm_kmappings here? They are not counted in the object. | |||||
Done Inline Actionskib suggested elsewhere that we should ignore kernel mappings for sealing purposes, so I backed down on checking it. kevans: kib suggested elsewhere that we should ignore kernel mappings for sealing purposes, so I backed… | |||||
return (0); | |||||
} | |||||
static int | |||||
shm_get_seals(struct file *fp, int *seals) | |||||
{ | |||||
struct shmfd *shmfd; | |||||
shmfd = fp->f_data; | |||||
SHM_SEAL_SLOCK(shmfd); | |||||
kibUnsubmitted Done Inline ActionsI think there is no point is taking the lock there. kib: I think there is no point is taking the lock there. | |||||
kevansAuthorUnsubmitted Done Inline ActionsThis one I was attempting to guarantee that any pending F_ADD_SEALS had finished completion prior to fetching the current seal. This may have been a foolish prospect, though, as there could be at least a couple of problems with that. kevans: This one I was attempting to guarantee that any pending F_ADD_SEALS had finished completion… | |||||
*seals = shmfd->shm_seals; | |||||
SHM_SEAL_SUNLOCK(shmfd); | |||||
return (0); | |||||
} | } | ||||
static int | static int | ||||
sysctl_posix_shm_list(SYSCTL_HANDLER_ARGS) | sysctl_posix_shm_list(SYSCTL_HANDLER_ARGS) | ||||
{ | { | ||||
struct shm_mapping *shmm; | struct shm_mapping *shmm; | ||||
struct sbuf sb; | struct sbuf sb; | ||||
struct kinfo_file kif; | struct kinfo_file kif; | ||||
Show All 38 Lines |
I do not think this blank line is useful.