mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-02 08:42:48 +00:00
swap_pager: Handle large swap_pager_reserve() requests
This interface is used solely by md(4) when the MD_RESERVE flag is specified, as in `mdconfig -a -t swap -s 1G -o reserve`. It pre-allocates swap blocks for the entire object. The number of blocks to be reserved is specified as a vm_size_t, but swp_pager_getswapspace() can allocate at most INT_MAX blocks. vm_size_t also seems like the incorrect type to use here it refers only to the size of the VM object, not the size of a mapping. So: - change the type of "size" in swap_pager_reserve() to vm_pindex_t, and - clamp the requested number of blocks for a single swp_pager_getswapspace() call to INT_MAX. Reported by: syzkaller Reviewed by: dougm, alc, kib MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D31875
This commit is contained in:
parent
a40c4ae866
commit
686aa9287c
@ -82,6 +82,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/eventhandler.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/limits.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/mount.h>
|
||||
@ -977,15 +978,16 @@ swap_pager_freespace(vm_object_t object, vm_pindex_t start, vm_size_t size)
|
||||
* Returns 0 on success, -1 on failure.
|
||||
*/
|
||||
int
|
||||
swap_pager_reserve(vm_object_t object, vm_pindex_t start, vm_size_t size)
|
||||
swap_pager_reserve(vm_object_t object, vm_pindex_t start, vm_pindex_t size)
|
||||
{
|
||||
daddr_t addr, blk, n_free, s_free;
|
||||
int i, j, n;
|
||||
vm_pindex_t i, j;
|
||||
int n;
|
||||
|
||||
swp_pager_init_freerange(&s_free, &n_free);
|
||||
VM_OBJECT_WLOCK(object);
|
||||
for (i = 0; i < size; i += n) {
|
||||
n = size - i;
|
||||
n = MIN(size - i, INT_MAX);
|
||||
blk = swp_pager_getswapspace(&n);
|
||||
if (blk == SWAPBLK_NONE) {
|
||||
swp_pager_meta_free(object, start, i);
|
||||
|
@ -78,7 +78,7 @@ void swap_pager_copy(vm_object_t, vm_object_t, vm_pindex_t, int);
|
||||
vm_pindex_t swap_pager_find_least(vm_object_t object, vm_pindex_t pindex);
|
||||
void swap_pager_swap_init(void);
|
||||
int swap_pager_nswapdev(void);
|
||||
int swap_pager_reserve(vm_object_t, vm_pindex_t, vm_size_t);
|
||||
int swap_pager_reserve(vm_object_t, vm_pindex_t, vm_pindex_t);
|
||||
void swap_pager_status(int *total, int *used);
|
||||
u_long swap_pager_swapped_pages(vm_object_t object);
|
||||
void swapoff_all(void);
|
||||
|
Loading…
Reference in New Issue
Block a user