mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-19 06:44:31 +00:00
MFp4: Several clean-ups and improvements over tmpfs:
- Remove tmpfs_zone_xxx KPI, the uma(9) wrapper, since they does not bring any value now. - Use |= instead of = when applying VV_ROOT flag. - Remove tm_avariable_nodes list. Use uma to hold the released nodes. - init/destory interlock mutex of node when init/fini instead of ctor/dtor. - Change memory computing using u_int to fix negative value in 2G mem machine. - Remove unnecessary bzero's - Rely uma logic to make file id allocation harder to guess. - Fix some unsigned/signed related things. Make sure we respect -o size=xxxx - Use wire instead of hold a page. - Pass allocate_zero to obtain zeroed pages upon first use. Submitted by: Howard Su Approved by: re (tmpfs blanket, kensmith)
This commit is contained in:
parent
16dbcac063
commit
7adb177693
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=171029
|
@ -314,7 +314,6 @@ struct tmpfs_mount {
|
|||
* they will go into the available list, remaining alive until the
|
||||
* file system is unmounted. */
|
||||
struct tmpfs_node_list tm_nodes_used;
|
||||
struct tmpfs_node_list tm_nodes_avail;
|
||||
|
||||
/* All node lock to protect the node list and tmp_pages_used */
|
||||
struct mtx allnode_lock;
|
||||
|
@ -470,10 +469,14 @@ TMPFS_PAGES_MAX(struct tmpfs_mount *tmp)
|
|||
}
|
||||
|
||||
/* Returns the available space for the given file system. */
|
||||
#define TMPFS_META_SIZE(tmp) ((tmp)->tm_nodes_inuse * (sizeof(struct tmpfs_node) \
|
||||
+ sizeof(struct dirent)))
|
||||
#define TMPFS_PAGES_AVAIL(tmp) (TMPFS_PAGES_MAX(tmp) - (tmp)->tm_pages_used - \
|
||||
TMPFS_META_SIZE(tmp) / PAGE_SIZE - 1)
|
||||
#define TMPFS_META_PAGES(tmp) ((tmp)->tm_nodes_inuse * (sizeof(struct tmpfs_node) \
|
||||
+ sizeof(struct tmpfs_dirent))/PAGE_SIZE + 1)
|
||||
#define TMPFS_FILE_PAGES(tmp) ((tmp)->tm_pages_used)
|
||||
|
||||
#define TMPFS_PAGES_AVAIL(tmp) (TMPFS_PAGES_MAX(tmp) > \
|
||||
TMPFS_META_PAGES(tmp)+TMPFS_FILE_PAGES(tmp)? \
|
||||
TMPFS_PAGES_MAX(tmp) - TMPFS_META_PAGES(tmp) \
|
||||
- TMPFS_FILE_PAGES(tmp):0)
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -100,47 +100,23 @@ tmpfs_alloc_node(struct tmpfs_mount *tmp, enum vtype type,
|
|||
MPASS(IFF(type == VLNK, target != NULL));
|
||||
MPASS(IFF(type == VBLK || type == VCHR, rdev != VNOVAL));
|
||||
|
||||
nnode = NULL;
|
||||
if (tmp->tm_nodes_inuse > tmp->tm_nodes_max)
|
||||
return (ENOSPC);
|
||||
|
||||
TMPFS_LOCK(tmp);
|
||||
if (LIST_EMPTY(&tmp->tm_nodes_avail)) {
|
||||
MPASS(tmp->tm_nodes_last <= tmp->tm_nodes_max);
|
||||
if (tmp->tm_nodes_last == tmp->tm_nodes_max) {
|
||||
TMPFS_UNLOCK(tmp);
|
||||
return ENOSPC;
|
||||
}
|
||||
TMPFS_UNLOCK(tmp);
|
||||
nnode = (struct tmpfs_node *)tmpfs_zone_alloc(
|
||||
tmp->tm_node_pool, M_WAITOK);
|
||||
if (nnode == NULL)
|
||||
return ENOSPC;
|
||||
nnode->tn_id = tmp->tm_nodes_last++;
|
||||
nnode->tn_gen = arc4random();
|
||||
} else {
|
||||
nnode = LIST_FIRST(&tmp->tm_nodes_avail);
|
||||
LIST_REMOVE(nnode, tn_entries);
|
||||
TMPFS_UNLOCK(tmp);
|
||||
nnode->tn_gen++;
|
||||
}
|
||||
MPASS(nnode != NULL);
|
||||
nnode = (struct tmpfs_node *)uma_zalloc_arg(
|
||||
tmp->tm_node_pool, tmp, M_WAITOK);
|
||||
if (nnode == NULL)
|
||||
return (ENOSPC);
|
||||
|
||||
/* Generic initialization. */
|
||||
nnode->tn_type = type;
|
||||
nnode->tn_size = 0;
|
||||
nnode->tn_status = 0;
|
||||
nnode->tn_flags = 0;
|
||||
nnode->tn_links = 0;
|
||||
nanotime(&nnode->tn_atime);
|
||||
nnode->tn_birthtime = nnode->tn_ctime = nnode->tn_mtime =
|
||||
nnode->tn_atime;
|
||||
nnode->tn_uid = uid;
|
||||
nnode->tn_gid = gid;
|
||||
nnode->tn_mode = mode;
|
||||
nnode->tn_lockf = NULL;
|
||||
nnode->tn_vnode = NULL;
|
||||
|
||||
nnode->tn_vpstate = 0;
|
||||
mtx_init(&nnode->tn_interlock, "tmpfs node interlock", NULL, MTX_DEF);
|
||||
/* Type-specific initialization. */
|
||||
switch (nnode->tn_type) {
|
||||
case VBLK:
|
||||
|
@ -169,7 +145,7 @@ tmpfs_alloc_node(struct tmpfs_mount *tmp, enum vtype type,
|
|||
M_WAITOK, nnode->tn_size);
|
||||
if (nnode->tn_link == NULL) {
|
||||
nnode->tn_type = VNON;
|
||||
tmpfs_free_node(tmp, nnode);
|
||||
uma_zfree(tmp->tm_node_pool, nnode);
|
||||
return ENOSPC;
|
||||
}
|
||||
memcpy(nnode->tn_link, target, nnode->tn_size);
|
||||
|
@ -216,9 +192,7 @@ tmpfs_alloc_node(struct tmpfs_mount *tmp, enum vtype type,
|
|||
void
|
||||
tmpfs_free_node(struct tmpfs_mount *tmp, struct tmpfs_node *node)
|
||||
{
|
||||
ino_t id;
|
||||
unsigned long gen;
|
||||
size_t pages;
|
||||
size_t pages = 0;
|
||||
|
||||
TMPFS_LOCK(tmp);
|
||||
LIST_REMOVE(node, tn_entries);
|
||||
|
@ -240,38 +214,28 @@ tmpfs_free_node(struct tmpfs_mount *tmp, struct tmpfs_node *node)
|
|||
case VFIFO:
|
||||
/* FALLTHROUGH */
|
||||
case VSOCK:
|
||||
pages = 0;
|
||||
break;
|
||||
|
||||
case VLNK:
|
||||
tmpfs_str_zone_free(&tmp->tm_str_pool, node->tn_link,
|
||||
node->tn_size);
|
||||
pages = 0;
|
||||
break;
|
||||
|
||||
case VREG:
|
||||
if (node->tn_reg.tn_aobj != NULL) {
|
||||
vm_object_deallocate(node->tn_reg.tn_aobj);
|
||||
node->tn_reg.tn_aobj = 0;
|
||||
}
|
||||
pages = node->tn_reg.tn_aobj_pages;
|
||||
break;
|
||||
|
||||
default:
|
||||
MPASS(0);
|
||||
pages = 0; /* Shut up gcc when !DIAGNOSTIC. */
|
||||
break;
|
||||
}
|
||||
|
||||
id = node->tn_id;
|
||||
gen = node->tn_gen;
|
||||
memset(node, 0, sizeof(struct tmpfs_node));
|
||||
node->tn_id = id;
|
||||
node->tn_type = VNON;
|
||||
node->tn_gen = gen;
|
||||
uma_zfree(tmp->tm_node_pool, node);
|
||||
|
||||
TMPFS_LOCK(tmp);
|
||||
LIST_INSERT_HEAD(&tmp->tm_nodes_avail, node, tn_entries);
|
||||
tmp->tm_pages_used -= pages;
|
||||
TMPFS_UNLOCK(tmp);
|
||||
}
|
||||
|
@ -293,14 +257,14 @@ tmpfs_alloc_dirent(struct tmpfs_mount *tmp, struct tmpfs_node *node,
|
|||
{
|
||||
struct tmpfs_dirent *nde;
|
||||
|
||||
nde = (struct tmpfs_dirent *)tmpfs_zone_alloc(
|
||||
nde = (struct tmpfs_dirent *)uma_zalloc(
|
||||
tmp->tm_dirent_pool, M_WAITOK);
|
||||
if (nde == NULL)
|
||||
return ENOSPC;
|
||||
|
||||
nde->td_name = tmpfs_str_zone_alloc(&tmp->tm_str_pool, M_WAITOK, len);
|
||||
if (nde->td_name == NULL) {
|
||||
tmpfs_zone_free(tmp->tm_dirent_pool, nde);
|
||||
uma_zfree(tmp->tm_dirent_pool, nde);
|
||||
return ENOSPC;
|
||||
}
|
||||
nde->td_namelen = len;
|
||||
|
@ -339,7 +303,7 @@ tmpfs_free_dirent(struct tmpfs_mount *tmp, struct tmpfs_dirent *de,
|
|||
}
|
||||
|
||||
tmpfs_str_zone_free(&tmp->tm_str_pool, de->td_name, de->td_namelen);
|
||||
tmpfs_zone_free(tmp->tm_dirent_pool, de);
|
||||
uma_zfree(tmp->tm_dirent_pool, de);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
@ -576,7 +540,6 @@ tmpfs_dir_attach(struct vnode *vp, struct tmpfs_dirent *de)
|
|||
dnode->tn_size += sizeof(struct tmpfs_dirent);
|
||||
dnode->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED | \
|
||||
TMPFS_NODE_MODIFIED;
|
||||
vnode_pager_setsize(vp, dnode->tn_size);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
@ -602,8 +565,6 @@ tmpfs_dir_detach(struct vnode *vp, struct tmpfs_dirent *de)
|
|||
dnode->tn_size -= sizeof(struct tmpfs_dirent);
|
||||
dnode->tn_status |= TMPFS_NODE_ACCESSED | TMPFS_NODE_CHANGED | \
|
||||
TMPFS_NODE_MODIFIED;
|
||||
|
||||
vnode_pager_setsize(vp, dnode->tn_size);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
@ -905,7 +866,7 @@ tmpfs_reg_resize(struct vnode *vp, off_t newsize)
|
|||
node->tn_size = newsize;
|
||||
vnode_pager_setsize(vp, newsize);
|
||||
if (newsize < oldsize) {
|
||||
int zerolen = MIN(round_page(newsize), node->tn_size) - newsize;
|
||||
size_t zerolen = MIN(round_page(newsize), node->tn_size) - newsize;
|
||||
struct vm_object *uobj = node->tn_reg.tn_aobj;
|
||||
vm_page_t m;
|
||||
|
||||
|
|
|
@ -32,29 +32,17 @@ __FBSDID("$FreeBSD$");
|
|||
|
||||
#include <fs/tmpfs/tmpfs.h>
|
||||
|
||||
uma_zone_t
|
||||
tmpfs_zone_create(char *name, int size, int align, struct tmpfs_mount *tmp)
|
||||
{
|
||||
uma_zone_t z;
|
||||
z = uma_zcreate(name, size, NULL, NULL, NULL, NULL, align, M_WAITOK);
|
||||
return z;
|
||||
}
|
||||
|
||||
void
|
||||
tmpfs_zone_destroy(uma_zone_t zone)
|
||||
{
|
||||
uma_zdestroy(zone);
|
||||
}
|
||||
|
||||
void
|
||||
tmpfs_str_zone_create(struct tmpfs_str_zone *tsz, struct tmpfs_mount *tmp)
|
||||
tmpfs_str_zone_create(struct tmpfs_str_zone *tsz)
|
||||
{
|
||||
int i, len;
|
||||
|
||||
len = TMPFS_STRZONE_STARTLEN;
|
||||
for (i = 0; i < TMPFS_STRZONE_ZONECOUNT; ++i) {
|
||||
tsz->tsz_zone[i] = tmpfs_zone_create(
|
||||
"TMPFS str", len, UMA_ALIGN_PTR, tmp);
|
||||
tsz->tsz_zone[i] = uma_zcreate(
|
||||
"TMPFS str", len,
|
||||
NULL, NULL, NULL, NULL,
|
||||
UMA_ALIGN_PTR, 0);
|
||||
len <<= 1;
|
||||
}
|
||||
}
|
||||
|
@ -66,7 +54,7 @@ tmpfs_str_zone_destroy(struct tmpfs_str_zone *tsz)
|
|||
|
||||
len = TMPFS_STRZONE_STARTLEN;
|
||||
for (i = 0; i < TMPFS_STRZONE_ZONECOUNT; ++i) {
|
||||
tmpfs_zone_destroy(tsz->tsz_zone[i]);
|
||||
uma_zdestroy(tsz->tsz_zone[i]);
|
||||
len <<= 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,26 +44,14 @@ uma_zone_t tmpfs_zone_create(char *name, int size, int align,
|
|||
struct tmpfs_mount *m);
|
||||
void tmpfs_zone_destroy(uma_zone_t zone);
|
||||
|
||||
static __inline void*
|
||||
tmpfs_zone_alloc(uma_zone_t zone, int flags)
|
||||
{
|
||||
return uma_zalloc(zone, flags);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
tmpfs_zone_free(uma_zone_t zone, void *item)
|
||||
{
|
||||
uma_zfree(zone, item);
|
||||
}
|
||||
|
||||
void tmpfs_str_zone_create(struct tmpfs_str_zone *, struct tmpfs_mount *);
|
||||
void tmpfs_str_zone_create(struct tmpfs_str_zone *);
|
||||
void tmpfs_str_zone_destroy(struct tmpfs_str_zone *);
|
||||
|
||||
static __inline char*
|
||||
tmpfs_str_zone_alloc(struct tmpfs_str_zone *tsz, int flags, size_t len)
|
||||
{
|
||||
|
||||
int i, zlen;
|
||||
size_t i, zlen;
|
||||
char *ptr;
|
||||
|
||||
MPASS(len <= (TMPFS_STRZONE_STARTLEN << (TMPFS_STRZONE_ZONECOUNT-1)));
|
||||
|
@ -74,14 +62,14 @@ tmpfs_str_zone_alloc(struct tmpfs_str_zone *tsz, int flags, size_t len)
|
|||
++i;
|
||||
zlen <<= 1;
|
||||
}
|
||||
ptr = (char *)tmpfs_zone_alloc(tsz->tsz_zone[i], flags);
|
||||
ptr = (char *)uma_zalloc(tsz->tsz_zone[i], flags);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static __inline void
|
||||
tmpfs_str_zone_free(struct tmpfs_str_zone *tsz, char *item, size_t len)
|
||||
{
|
||||
int i, zlen;
|
||||
size_t i, zlen;
|
||||
|
||||
MPASS(len <= (TMPFS_STRZONE_STARTLEN << (TMPFS_STRZONE_ZONECOUNT-1)));
|
||||
|
||||
|
@ -91,7 +79,7 @@ tmpfs_str_zone_free(struct tmpfs_str_zone *tsz, char *item, size_t len)
|
|||
++i;
|
||||
zlen <<= 1;
|
||||
}
|
||||
tmpfs_zone_free(tsz->tsz_zone[i], item);
|
||||
uma_zfree(tsz->tsz_zone[i], item);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -91,13 +91,13 @@ static const char *tmpfs_opts[] = {
|
|||
|
||||
#define SWI_MAXMIB 3
|
||||
|
||||
static int
|
||||
static u_int
|
||||
get_swpgtotal(void)
|
||||
{
|
||||
struct xswdev xsd;
|
||||
char *sname = "vm.swap_info";
|
||||
int soid[SWI_MAXMIB], oid[2];
|
||||
int unswdev, total, dmmax, nswapdev;
|
||||
u_int unswdev, total, dmmax, nswapdev;
|
||||
size_t mibi, len;
|
||||
|
||||
total = 0;
|
||||
|
@ -139,6 +139,60 @@ get_swpgtotal(void)
|
|||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
static int
|
||||
tmpfs_node_ctor(void *mem, int size, void *arg, int flags)
|
||||
{
|
||||
struct tmpfs_node *node = (struct tmpfs_node *)mem;
|
||||
|
||||
if (node->tn_id == 0) {
|
||||
/* if this node structure first time used */
|
||||
struct tmpfs_mount *tmp = (struct tmpfs_mount *)arg;
|
||||
TMPFS_LOCK(tmp);
|
||||
node->tn_id = tmp->tm_nodes_last++;
|
||||
TMPFS_UNLOCK(tmp);
|
||||
node->tn_gen = arc4random();
|
||||
}
|
||||
else {
|
||||
node->tn_gen++;
|
||||
}
|
||||
|
||||
node->tn_size = 0;
|
||||
node->tn_status = 0;
|
||||
node->tn_flags = 0;
|
||||
node->tn_links = 0;
|
||||
node->tn_lockf = NULL;
|
||||
node->tn_vnode = NULL;
|
||||
node->tn_vpstate = 0;
|
||||
node->tn_lookup_dirent = NULL;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
tmpfs_node_dtor(void *mem, int size, void *arg)
|
||||
{
|
||||
struct tmpfs_node *node = (struct tmpfs_node *)mem;
|
||||
node->tn_type = VNON;
|
||||
}
|
||||
|
||||
static int
|
||||
tmpfs_node_init(void *mem, int size, int flags)
|
||||
{
|
||||
struct tmpfs_node *node = (struct tmpfs_node *)mem;
|
||||
node->tn_id = 0;
|
||||
|
||||
mtx_init(&node->tn_interlock, "tmpfs node interlock", NULL, MTX_DEF);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
tmpfs_node_fini(void *mem, int size)
|
||||
{
|
||||
struct tmpfs_node *node = (struct tmpfs_node *)mem;
|
||||
|
||||
mtx_destroy(&node->tn_interlock);
|
||||
}
|
||||
|
||||
static int
|
||||
tmpfs_mount(struct mount *mp, struct thread *l)
|
||||
|
@ -208,21 +262,23 @@ tmpfs_mount(struct mount *mp, struct thread *l)
|
|||
tmp->tm_nodes_inuse = 0;
|
||||
tmp->tm_maxfilesize = get_swpgtotal() * PAGE_SIZE;
|
||||
LIST_INIT(&tmp->tm_nodes_used);
|
||||
LIST_INIT(&tmp->tm_nodes_avail);
|
||||
|
||||
|
||||
tmp->tm_pages_max = pages;
|
||||
tmp->tm_pages_used = 0;
|
||||
tmp->tm_dirent_pool = tmpfs_zone_create(
|
||||
tmp->tm_dirent_pool = uma_zcreate(
|
||||
"TMPFS dirent",
|
||||
sizeof(struct tmpfs_dirent),
|
||||
NULL, NULL, NULL, NULL,
|
||||
UMA_ALIGN_PTR,
|
||||
tmp);
|
||||
tmp->tm_node_pool = tmpfs_zone_create(
|
||||
0);
|
||||
tmp->tm_node_pool = uma_zcreate(
|
||||
"TMPFS node",
|
||||
sizeof(struct tmpfs_node),
|
||||
tmpfs_node_ctor, tmpfs_node_dtor,
|
||||
tmpfs_node_init, tmpfs_node_fini,
|
||||
UMA_ALIGN_PTR,
|
||||
tmp);
|
||||
tmpfs_str_zone_create(&tmp->tm_str_pool, tmp);
|
||||
0);
|
||||
tmpfs_str_zone_create(&tmp->tm_str_pool);
|
||||
|
||||
/* Allocate the root node. */
|
||||
error = tmpfs_alloc_node(tmp, VDIR, args.ta_root_uid,
|
||||
|
@ -231,8 +287,8 @@ tmpfs_mount(struct mount *mp, struct thread *l)
|
|||
|
||||
if (error != 0 || root == NULL) {
|
||||
tmpfs_str_zone_destroy(&tmp->tm_str_pool);
|
||||
tmpfs_zone_destroy(tmp->tm_node_pool);
|
||||
tmpfs_zone_destroy(tmp->tm_dirent_pool);
|
||||
uma_zdestroy(tmp->tm_node_pool);
|
||||
uma_zdestroy(tmp->tm_dirent_pool);
|
||||
free(tmp, M_TMPFSMNT);
|
||||
return error;
|
||||
}
|
||||
|
@ -300,18 +356,9 @@ tmpfs_unmount(struct mount *mp, int mntflags, struct thread *l)
|
|||
tmpfs_free_node(tmp, node);
|
||||
node = next;
|
||||
}
|
||||
node = LIST_FIRST(&tmp->tm_nodes_avail);
|
||||
while (node != NULL) {
|
||||
struct tmpfs_node *next;
|
||||
|
||||
next = LIST_NEXT(node, tn_entries);
|
||||
LIST_REMOVE(node, tn_entries);
|
||||
tmpfs_zone_free(tmp->tm_node_pool, node);
|
||||
node = next;
|
||||
}
|
||||
|
||||
tmpfs_zone_destroy(tmp->tm_dirent_pool);
|
||||
tmpfs_zone_destroy(tmp->tm_node_pool);
|
||||
uma_zdestroy(tmp->tm_dirent_pool);
|
||||
uma_zdestroy(tmp->tm_node_pool);
|
||||
tmpfs_str_zone_destroy(&tmp->tm_str_pool);
|
||||
|
||||
mtx_destroy(&tmp->allnode_lock);
|
||||
|
@ -336,7 +383,7 @@ tmpfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td)
|
|||
error = tmpfs_alloc_vp(mp, VFS_TO_TMPFS(mp)->tm_root, vpp, td);
|
||||
|
||||
if (!error)
|
||||
(*vpp)->v_vflag = VV_ROOT;
|
||||
(*vpp)->v_vflag |= VV_ROOT;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
|
|
@ -501,13 +501,10 @@ tmpfs_uio_xfer(struct tmpfs_mount *tmp, struct tmpfs_node *node,
|
|||
idx = OFF_TO_IDX(uio->uio_offset);
|
||||
d = uio->uio_offset - IDX_TO_OFF(idx);
|
||||
len = MIN(len, (PAGE_SIZE - d));
|
||||
m = vm_page_grab(uobj, idx, VM_ALLOC_NORMAL | VM_ALLOC_RETRY);
|
||||
m = vm_page_grab(uobj, idx, VM_ALLOC_WIRED | VM_ALLOC_ZERO |
|
||||
VM_ALLOC_NORMAL | VM_ALLOC_RETRY);
|
||||
if (uio->uio_rw == UIO_READ && m->valid != VM_PAGE_BITS_ALL)
|
||||
if (vm_pager_get_pages(uobj, &m, 1, 0) != VM_PAGER_OK)
|
||||
vm_page_zero_invalid(m, TRUE);
|
||||
vm_page_lock_queues();
|
||||
vm_page_hold(m);
|
||||
vm_page_unlock_queues();
|
||||
vm_page_zero_invalid(m, TRUE);
|
||||
VM_OBJECT_UNLOCK(uobj);
|
||||
sched_pin();
|
||||
sf = sf_buf_alloc(m, SFB_CPUPRIVATE);
|
||||
|
@ -521,7 +518,7 @@ tmpfs_uio_xfer(struct tmpfs_mount *tmp, struct tmpfs_node *node,
|
|||
vm_page_zero_invalid(m, TRUE);
|
||||
vm_page_dirty(m);
|
||||
}
|
||||
vm_page_unhold(m);
|
||||
vm_page_unwire(m, 0);
|
||||
vm_page_activate(m);
|
||||
vm_page_wakeup(m);
|
||||
vm_page_unlock_queues();
|
||||
|
|
Loading…
Reference in a new issue