Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/vfs_default.c
Show First 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | |||||
#include <sys/mount.h> | #include <sys/mount.h> | ||||
#include <sys/namei.h> | #include <sys/namei.h> | ||||
#include <sys/rwlock.h> | #include <sys/rwlock.h> | ||||
#include <sys/fcntl.h> | #include <sys/fcntl.h> | ||||
#include <sys/unistd.h> | #include <sys/unistd.h> | ||||
#include <sys/vnode.h> | #include <sys/vnode.h> | ||||
#include <sys/dirent.h> | #include <sys/dirent.h> | ||||
#include <sys/poll.h> | #include <sys/poll.h> | ||||
#include <sys/stat.h> | |||||
#include <security/audit/audit.h> | |||||
#include <sys/priv.h> | |||||
#include <security/mac/mac_framework.h> | #include <security/mac/mac_framework.h> | ||||
#include <vm/vm.h> | #include <vm/vm.h> | ||||
#include <vm/vm_object.h> | #include <vm/vm_object.h> | ||||
#include <vm/vm_extern.h> | #include <vm/vm_extern.h> | ||||
#include <vm/pmap.h> | #include <vm/pmap.h> | ||||
#include <vm/vm_map.h> | #include <vm/vm_map.h> | ||||
Show All 14 Lines | |||||
#define DIRENT_MINSIZE (sizeof(struct dirent) - (MAXNAMLEN+1) + 4) | #define DIRENT_MINSIZE (sizeof(struct dirent) - (MAXNAMLEN+1) + 4) | ||||
static int vop_stdis_text(struct vop_is_text_args *ap); | static int vop_stdis_text(struct vop_is_text_args *ap); | ||||
static int vop_stdunset_text(struct vop_unset_text_args *ap); | static int vop_stdunset_text(struct vop_unset_text_args *ap); | ||||
static int vop_stdadd_writecount(struct vop_add_writecount_args *ap); | static int vop_stdadd_writecount(struct vop_add_writecount_args *ap); | ||||
static int vop_stdcopy_file_range(struct vop_copy_file_range_args *ap); | static int vop_stdcopy_file_range(struct vop_copy_file_range_args *ap); | ||||
static int vop_stdfdatasync(struct vop_fdatasync_args *ap); | static int vop_stdfdatasync(struct vop_fdatasync_args *ap); | ||||
static int vop_stdgetpages_async(struct vop_getpages_async_args *ap); | static int vop_stdgetpages_async(struct vop_getpages_async_args *ap); | ||||
static int vop_stdstat(struct vop_stat_args *ap); | |||||
/* | /* | ||||
* This vnode table stores what we want to do if the filesystem doesn't | * This vnode table stores what we want to do if the filesystem doesn't | ||||
* implement a particular VOP. | * implement a particular VOP. | ||||
* | * | ||||
* If there is no specific entry here, we will return EOPNOTSUPP. | * If there is no specific entry here, we will return EOPNOTSUPP. | ||||
* | * | ||||
* Note that every filesystem has to implement either vop_access | * Note that every filesystem has to implement either vop_access | ||||
Show All 11 Lines | struct vop_vector default_vnodeops = { | ||||
.vop_advise = vop_stdadvise, | .vop_advise = vop_stdadvise, | ||||
.vop_advlock = vop_stdadvlock, | .vop_advlock = vop_stdadvlock, | ||||
.vop_advlockasync = vop_stdadvlockasync, | .vop_advlockasync = vop_stdadvlockasync, | ||||
.vop_advlockpurge = vop_stdadvlockpurge, | .vop_advlockpurge = vop_stdadvlockpurge, | ||||
.vop_allocate = vop_stdallocate, | .vop_allocate = vop_stdallocate, | ||||
.vop_bmap = vop_stdbmap, | .vop_bmap = vop_stdbmap, | ||||
.vop_close = VOP_NULL, | .vop_close = VOP_NULL, | ||||
.vop_fsync = VOP_NULL, | .vop_fsync = VOP_NULL, | ||||
.vop_stat = vop_stdstat, | |||||
.vop_fdatasync = vop_stdfdatasync, | .vop_fdatasync = vop_stdfdatasync, | ||||
.vop_getpages = vop_stdgetpages, | .vop_getpages = vop_stdgetpages, | ||||
.vop_getpages_async = vop_stdgetpages_async, | .vop_getpages_async = vop_stdgetpages_async, | ||||
.vop_getwritemount = vop_stdgetwritemount, | .vop_getwritemount = vop_stdgetwritemount, | ||||
.vop_inactive = VOP_NULL, | .vop_inactive = VOP_NULL, | ||||
.vop_need_inactive = vop_stdneed_inactive, | .vop_need_inactive = vop_stdneed_inactive, | ||||
.vop_ioctl = vop_stdioctl, | .vop_ioctl = vop_stdioctl, | ||||
.vop_kqfilter = vop_stdkqfilter, | .vop_kqfilter = vop_stdkqfilter, | ||||
▲ Show 20 Lines • Show All 1,330 Lines • ▼ Show 20 Lines | vop_sigdefer(struct vop_vector *vop, struct vop_generic_args *a) | ||||
bp = bp_by_off(vop, a); | bp = bp_by_off(vop, a); | ||||
MPASS(bp != NULL); | MPASS(bp != NULL); | ||||
prev_stops = sigdeferstop(SIGDEFERSTOP_SILENT); | prev_stops = sigdeferstop(SIGDEFERSTOP_SILENT); | ||||
rc = bp(a); | rc = bp(a); | ||||
sigallowstop(prev_stops); | sigallowstop(prev_stops); | ||||
return (rc); | return (rc); | ||||
} | |||||
static int | |||||
vop_stdstat(struct vop_stat_args *a) | |||||
{ | |||||
struct vattr vattr; | |||||
struct vattr *vap; | |||||
struct vnode *vp; | |||||
struct stat *sb; | |||||
int error; | |||||
u_short mode; | |||||
vp = a->a_vp; | |||||
sb = a->a_sb; | |||||
error = vop_stat_helper_pre(a); | |||||
if (error != 0) | |||||
return (error); | |||||
vap = &vattr; | |||||
/* | |||||
* Initialize defaults for new and unusual fields, so that file | |||||
* systems which don't support these fields don't need to know | |||||
* about them. | |||||
*/ | |||||
vap->va_birthtime.tv_sec = -1; | |||||
vap->va_birthtime.tv_nsec = 0; | |||||
vap->va_fsid = VNOVAL; | |||||
vap->va_rdev = NODEV; | |||||
error = VOP_GETATTR(vp, vap, a->a_active_cred); | |||||
if (error) | |||||
kib: I would argue that post hook should be called regardless of error. | |||||
goto out; | |||||
/* | |||||
* Zero the spare stat fields | |||||
*/ | |||||
bzero(sb, sizeof *sb); | |||||
/* | |||||
* Copy from vattr table | |||||
*/ | |||||
if (vap->va_fsid != VNOVAL) | |||||
sb->st_dev = vap->va_fsid; | |||||
else | |||||
sb->st_dev = vp->v_mount->mnt_stat.f_fsid.val[0]; | |||||
sb->st_ino = vap->va_fileid; | |||||
mode = vap->va_mode; | |||||
switch (vap->va_type) { | |||||
case VREG: | |||||
mode |= S_IFREG; | |||||
break; | |||||
case VDIR: | |||||
mode |= S_IFDIR; | |||||
break; | |||||
case VBLK: | |||||
mode |= S_IFBLK; | |||||
break; | |||||
case VCHR: | |||||
mode |= S_IFCHR; | |||||
break; | |||||
case VLNK: | |||||
mode |= S_IFLNK; | |||||
break; | |||||
case VSOCK: | |||||
mode |= S_IFSOCK; | |||||
break; | |||||
case VFIFO: | |||||
mode |= S_IFIFO; | |||||
break; | |||||
default: | |||||
error = EBADF; | |||||
Not Done Inline ActionsThere kib: There | |||||
goto out; | |||||
} | |||||
sb->st_mode = mode; | |||||
sb->st_nlink = vap->va_nlink; | |||||
sb->st_uid = vap->va_uid; | |||||
sb->st_gid = vap->va_gid; | |||||
sb->st_rdev = vap->va_rdev; | |||||
Not Done Inline ActionsAnd there kib: And there | |||||
if (vap->va_size > OFF_MAX) { | |||||
error = EOVERFLOW; | |||||
goto out; | |||||
} | |||||
sb->st_size = vap->va_size; | |||||
sb->st_atim.tv_sec = vap->va_atime.tv_sec; | |||||
sb->st_atim.tv_nsec = vap->va_atime.tv_nsec; | |||||
sb->st_mtim.tv_sec = vap->va_mtime.tv_sec; | |||||
sb->st_mtim.tv_nsec = vap->va_mtime.tv_nsec; | |||||
sb->st_ctim.tv_sec = vap->va_ctime.tv_sec; | |||||
sb->st_ctim.tv_nsec = vap->va_ctime.tv_nsec; | |||||
sb->st_birthtim.tv_sec = vap->va_birthtime.tv_sec; | |||||
sb->st_birthtim.tv_nsec = vap->va_birthtime.tv_nsec; | |||||
/* | |||||
* According to www.opengroup.org, the meaning of st_blksize is | |||||
* "a filesystem-specific preferred I/O block size for this | |||||
* object. In some filesystem types, this may vary from file | |||||
* to file" | |||||
* Use minimum/default of PAGE_SIZE (e.g. for VCHR). | |||||
*/ | |||||
sb->st_blksize = max(PAGE_SIZE, vap->va_blocksize); | |||||
sb->st_flags = vap->va_flags; | |||||
sb->st_blocks = vap->va_bytes / S_BLKSIZE; | |||||
sb->st_gen = vap->va_gen; | |||||
out: | |||||
return (vop_stat_helper_post(a, error)); | |||||
} | } |
I would argue that post hook should be called regardless of error.