Changeset View
Changeset View
Standalone View
Standalone View
sys/fs/tmpfs/tmpfs_vfsops.c
Show All 38 Lines | ||||||||||
* sub-system to store file data and metadata in an efficient way. | * sub-system to store file data and metadata in an efficient way. | |||||||||
* This means that it does not follow the structure of an on-disk file | * This means that it does not follow the structure of an on-disk file | |||||||||
* system because it simply does not need to. Instead, it uses | * system because it simply does not need to. Instead, it uses | |||||||||
* memory-specific data structures and algorithms to automatically | * memory-specific data structures and algorithms to automatically | |||||||||
* allocate and release resources. | * allocate and release resources. | |||||||||
*/ | */ | |||||||||
#include "opt_tmpfs.h" | #include "opt_tmpfs.h" | |||||||||
#include "opt_ddb.h" | ||||||||||
markj: opt_ddb.h should be included first. | ||||||||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | |||||||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | |||||||||
#include <sys/param.h> | #include <sys/param.h> | |||||||||
#include <sys/systm.h> | #include <sys/systm.h> | |||||||||
#include <sys/dirent.h> | #include <sys/dirent.h> | |||||||||
#include <sys/file.h> | #include <sys/file.h> | |||||||||
▲ Show 20 Lines • Show All 185 Lines • ▼ Show 20 Lines | VM_MAP_ENTRY_FOREACH(entry, map) { | |||||||||
VM_OBJECT_RUNLOCK(object); | VM_OBJECT_RUNLOCK(object); | |||||||||
continue; | continue; | |||||||||
} | } | |||||||||
MPASS(object->ref_count > 1); | MPASS(object->ref_count > 1); | |||||||||
if ((object->flags & OBJ_TMPFS) == 0) { | if ((object->flags & OBJ_TMPFS) == 0) { | |||||||||
VM_OBJECT_RUNLOCK(object); | VM_OBJECT_RUNLOCK(object); | |||||||||
continue; | continue; | |||||||||
} | } | |||||||||
vp = object->un_pager.swp.swp_tmpfs; | vp = VM_TO_TMPFS_VP(object); | |||||||||
if (vp->v_mount != mp) { | if (vp->v_mount != mp) { | |||||||||
VM_OBJECT_RUNLOCK(object); | VM_OBJECT_RUNLOCK(object); | |||||||||
continue; | continue; | |||||||||
} | } | |||||||||
terminate = cb(mp, map, entry, cb_arg); | terminate = cb(mp, map, entry, cb_arg); | |||||||||
VM_OBJECT_RUNLOCK(object); | VM_OBJECT_RUNLOCK(object); | |||||||||
if (terminate) | if (terminate) | |||||||||
▲ Show 20 Lines • Show All 294 Lines • ▼ Show 20 Lines | tmpfs_free_tmp(struct tmpfs_mount *tmp) | |||||||||
tmp->tm_refcount--; | tmp->tm_refcount--; | |||||||||
if (tmp->tm_refcount > 0) { | if (tmp->tm_refcount > 0) { | |||||||||
TMPFS_UNLOCK(tmp); | TMPFS_UNLOCK(tmp); | |||||||||
return; | return; | |||||||||
} | } | |||||||||
TMPFS_UNLOCK(tmp); | TMPFS_UNLOCK(tmp); | |||||||||
mtx_destroy(&tmp->tm_allnode_lock); | mtx_destroy(&tmp->tm_allnode_lock); | |||||||||
MPASS(tmp->tm_pages_used == 0); | /* | |||||||||
* We cannot assert that tmp->tm_pages_used == 0 there, | ||||||||||
* because tmpfs vm_objects might be still mapped by some | ||||||||||
* process and outlive the mount due to reference counting. | ||||||||||
*/ | ||||||||||
MPASS(tmp->tm_nodes_inuse == 0); | MPASS(tmp->tm_nodes_inuse == 0); | |||||||||
free(tmp, M_TMPFSMNT); | free(tmp, M_TMPFSMNT); | |||||||||
} | } | |||||||||
static int | static int | |||||||||
tmpfs_root(struct mount *mp, int flags, struct vnode **vpp) | tmpfs_root(struct mount *mp, int flags, struct vnode **vpp) | |||||||||
{ | { | |||||||||
▲ Show 20 Lines • Show All 123 Lines • ▼ Show 20 Lines | struct vfsops tmpfs_vfsops = { | |||||||||
.vfs_cachedroot = tmpfs_root, | .vfs_cachedroot = tmpfs_root, | |||||||||
.vfs_statfs = tmpfs_statfs, | .vfs_statfs = tmpfs_statfs, | |||||||||
.vfs_fhtovp = tmpfs_fhtovp, | .vfs_fhtovp = tmpfs_fhtovp, | |||||||||
.vfs_sync = tmpfs_sync, | .vfs_sync = tmpfs_sync, | |||||||||
.vfs_init = tmpfs_init, | .vfs_init = tmpfs_init, | |||||||||
.vfs_uninit = tmpfs_uninit, | .vfs_uninit = tmpfs_uninit, | |||||||||
}; | }; | |||||||||
VFS_SET(tmpfs_vfsops, tmpfs, VFCF_JAIL); | VFS_SET(tmpfs_vfsops, tmpfs, VFCF_JAIL); | |||||||||
#ifdef DDB | ||||||||||
Done Inline Actions
markj: | ||||||||||
#include <ddb/ddb.h> | ||||||||||
static void | ||||||||||
db_print_tmpfs(struct mount *mp, struct tmpfs_mount *tmp) | ||||||||||
{ | ||||||||||
db_printf("mp %p (%s) tmp %p\n", mp, | ||||||||||
mp->mnt_stat.f_mntonname, tmp); | ||||||||||
db_printf( | ||||||||||
"\tsize max %ju pages max %lu pages used %lu\n" | ||||||||||
"\tinodes max %ju inodes inuse %ju refcount %ju\n" | ||||||||||
"\tmaxfilesize %ju r%c %snamecache %smtime\n", | ||||||||||
(uintmax_t)tmp->tm_size_max, tmp->tm_pages_max, tmp->tm_pages_used, | ||||||||||
(uintmax_t)tmp->tm_nodes_max, (uintmax_t)tmp->tm_nodes_inuse, | ||||||||||
(uintmax_t)tmp->tm_refcount, (uintmax_t)tmp->tm_maxfilesize, | ||||||||||
tmp->tm_ronly ? 'o' : 'w', tmp->tm_nonc ? "no" : "", | ||||||||||
tmp->tm_nomtime ? "no" : ""); | ||||||||||
} | ||||||||||
DB_SHOW_COMMAND(tmpfs, db_show_tmpfs) | ||||||||||
{ | ||||||||||
struct mount *mp; | ||||||||||
struct tmpfs_mount *tmp; | ||||||||||
if (have_addr) { | ||||||||||
mp = (struct mount *)addr; | ||||||||||
tmp = VFS_TO_TMPFS(mp); | ||||||||||
db_print_tmpfs(mp, tmp); | ||||||||||
return; | ||||||||||
} | ||||||||||
TAILQ_FOREACH(mp, &mountlist, mnt_list) { | ||||||||||
if (strcmp(mp->mnt_stat.f_fstypename, tmpfs_vfsconf.vfc_name) == | ||||||||||
0) { | ||||||||||
tmp = VFS_TO_TMPFS(mp); | ||||||||||
db_print_tmpfs(mp, tmp); | ||||||||||
} | ||||||||||
} | ||||||||||
} | ||||||||||
#endif /* DDB */ |
opt_ddb.h should be included first.