Changeset View
Changeset View
Standalone View
Standalone View
sys/fs/tmpfs/tmpfs_vnops.c
Show First 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | |||||
#include <sys/proc.h> | #include <sys/proc.h> | ||||
#include <sys/rwlock.h> | #include <sys/rwlock.h> | ||||
#include <sys/sched.h> | #include <sys/sched.h> | ||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/unistd.h> | #include <sys/unistd.h> | ||||
#include <sys/vnode.h> | #include <sys/vnode.h> | ||||
#include <sys/smr.h> | #include <sys/smr.h> | ||||
#include <security/audit/audit.h> | |||||
#include <security/mac/mac_framework.h> | |||||
#include <vm/vm.h> | #include <vm/vm.h> | ||||
#include <vm/vm_param.h> | #include <vm/vm_param.h> | ||||
#include <vm/vm_object.h> | #include <vm/vm_object.h> | ||||
#include <fs/tmpfs/tmpfs_vnops.h> | #include <fs/tmpfs/tmpfs_vnops.h> | ||||
#include <fs/tmpfs/tmpfs.h> | #include <fs/tmpfs/tmpfs.h> | ||||
▲ Show 20 Lines • Show All 334 Lines • ▼ Show 20 Lines | |||||
out: | out: | ||||
MPASS(VOP_ISLOCKED(vp)); | MPASS(VOP_ISLOCKED(vp)); | ||||
return error; | return error; | ||||
} | } | ||||
int | int | ||||
tmpfs_stat(struct vop_stat_args *v) | |||||
{ | |||||
struct vnode *vp = v->a_vp; | |||||
struct stat *sb = v->a_sb; | |||||
vm_object_t obj; | |||||
struct tmpfs_node *node; | |||||
int error; | |||||
node = VP_TO_TMPFS_NODE(vp); | |||||
tmpfs_update_getattr(vp); | |||||
error = vop_stat_helper_pre(v); | |||||
if (__predict_false(error)) | |||||
return (error); | |||||
sb->st_dev = vp->v_mount->mnt_stat.f_fsid.val[0]; | |||||
sb->st_ino = node->tn_id; | |||||
sb->st_mode = node->tn_mode | VTTOIF(vp->v_type); | |||||
sb->st_nlink = node->tn_links; | |||||
sb->st_uid = node->tn_uid; | |||||
sb->st_gid = node->tn_gid; | |||||
sb->st_rdev = (vp->v_type == VBLK || vp->v_type == VCHR) ? | |||||
node->tn_rdev : NODEV; | |||||
sb->st_size = node->tn_size; | |||||
sb->st_atim.tv_sec = node->tn_atime.tv_sec; | |||||
sb->st_atim.tv_nsec = node->tn_atime.tv_nsec; | |||||
sb->st_mtim.tv_sec = node->tn_mtime.tv_sec; | |||||
sb->st_mtim.tv_nsec = node->tn_mtime.tv_nsec; | |||||
sb->st_ctim.tv_sec = node->tn_ctime.tv_sec; | |||||
sb->st_ctim.tv_nsec = node->tn_ctime.tv_nsec; | |||||
sb->st_birthtim.tv_sec = node->tn_birthtime.tv_sec; | |||||
sb->st_birthtim.tv_nsec = node->tn_birthtime.tv_nsec; | |||||
sb->st_blksize = PAGE_SIZE; | |||||
sb->st_flags = node->tn_flags; | |||||
sb->st_gen = 0; | |||||
if (vp->v_type == VREG) { | |||||
obj = node->tn_reg.tn_aobj; | |||||
sb->st_blocks = (u_quad_t)obj->resident_page_count * PAGE_SIZE; | |||||
} else | |||||
sb->st_blocks = node->tn_size; | |||||
sb->st_blocks /= S_BLKSIZE; | |||||
return (vop_stat_helper_post(v, error)); | |||||
} | |||||
int | |||||
tmpfs_getattr(struct vop_getattr_args *v) | tmpfs_getattr(struct vop_getattr_args *v) | ||||
kib: Can we avoid having fs to implement both VOP_STAT and VOP_GETATTR if it wants to provide STAT ? | |||||
Done Inline ActionsNot right now unfortunately. GETATTR itself is cheaper to execute and called all the time (e.g., mmap). Most consumers are only looking to get the file size though and other cheaply obtainable subset. I had a WIP patch to implement a stripped down GETATTR which provides only what's needed by mmap/exec/lseek/sendfile. With that in place GETATTR itself would be rare enough that we could retire it and indeed create a wrapper around stat. mjg: Not right now unfortunately. GETATTR itself is cheaper to execute and called all the time (e.g. | |||||
{ | { | ||||
struct vnode *vp = v->a_vp; | struct vnode *vp = v->a_vp; | ||||
struct vattr *vap = v->a_vap; | struct vattr *vap = v->a_vap; | ||||
vm_object_t obj; | vm_object_t obj; | ||||
struct tmpfs_node *node; | struct tmpfs_node *node; | ||||
node = VP_TO_TMPFS_NODE(vp); | node = VP_TO_TMPFS_NODE(vp); | ||||
▲ Show 20 Lines • Show All 1,252 Lines • ▼ Show 20 Lines | struct vop_vector tmpfs_vnodeop_entries = { | ||||
.vop_lookup = vfs_cache_lookup, | .vop_lookup = vfs_cache_lookup, | ||||
.vop_cachedlookup = tmpfs_cached_lookup, | .vop_cachedlookup = tmpfs_cached_lookup, | ||||
.vop_create = tmpfs_create, | .vop_create = tmpfs_create, | ||||
.vop_mknod = tmpfs_mknod, | .vop_mknod = tmpfs_mknod, | ||||
.vop_open = tmpfs_open, | .vop_open = tmpfs_open, | ||||
.vop_close = tmpfs_close, | .vop_close = tmpfs_close, | ||||
.vop_fplookup_vexec = tmpfs_fplookup_vexec, | .vop_fplookup_vexec = tmpfs_fplookup_vexec, | ||||
.vop_access = tmpfs_access, | .vop_access = tmpfs_access, | ||||
.vop_stat = tmpfs_stat, | |||||
.vop_getattr = tmpfs_getattr, | .vop_getattr = tmpfs_getattr, | ||||
.vop_setattr = tmpfs_setattr, | .vop_setattr = tmpfs_setattr, | ||||
.vop_read = tmpfs_read, | .vop_read = tmpfs_read, | ||||
.vop_write = tmpfs_write, | .vop_write = tmpfs_write, | ||||
.vop_fsync = tmpfs_fsync, | .vop_fsync = tmpfs_fsync, | ||||
.vop_remove = tmpfs_remove, | .vop_remove = tmpfs_remove, | ||||
.vop_link = tmpfs_link, | .vop_link = tmpfs_link, | ||||
.vop_rename = tmpfs_rename, | .vop_rename = tmpfs_rename, | ||||
Show All 28 Lines |
Can we avoid having fs to implement both VOP_STAT and VOP_GETATTR if it wants to provide STAT ?