Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/vfs_vnops.c
Show First 20 Lines • Show All 1,449 Lines • ▼ Show 20 Lines | |||||
static int | static int | ||||
vn_statfile(struct file *fp, struct stat *sb, struct ucred *active_cred, | vn_statfile(struct file *fp, struct stat *sb, struct ucred *active_cred, | ||||
struct thread *td) | struct thread *td) | ||||
{ | { | ||||
struct vnode *vp = fp->f_vnode; | struct vnode *vp = fp->f_vnode; | ||||
int error; | int error; | ||||
vn_lock(vp, LK_SHARED | LK_RETRY); | vn_lock(vp, LK_SHARED | LK_RETRY); | ||||
error = vn_stat(vp, sb, active_cred, fp->f_cred, td); | error = VOP_STAT(vp, sb, active_cred, fp->f_cred, td); | ||||
VOP_UNLOCK(vp); | VOP_UNLOCK(vp); | ||||
return (error); | return (error); | ||||
} | |||||
/* | |||||
* Stat a vnode; implementation for the stat syscall | |||||
*/ | |||||
int | |||||
vn_stat(struct vnode *vp, struct stat *sb, struct ucred *active_cred, | |||||
struct ucred *file_cred, struct thread *td) | |||||
{ | |||||
struct vattr vattr; | |||||
struct vattr *vap; | |||||
int error; | |||||
u_short mode; | |||||
AUDIT_ARG_VNODE1(vp); | |||||
#ifdef MAC | |||||
error = mac_vnode_check_stat(active_cred, file_cred, vp); | |||||
if (error) | |||||
return (error); | |||||
#endif | |||||
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, active_cred); | |||||
if (error) | |||||
return (error); | |||||
/* | |||||
* 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: | |||||
return (EBADF); | |||||
} | |||||
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; | |||||
if (vap->va_size > OFF_MAX) | |||||
return (EOVERFLOW); | |||||
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; | |||||
if (priv_check_cred_vfs_generation(td->td_ucred)) | |||||
sb->st_gen = 0; | |||||
else | |||||
sb->st_gen = vap->va_gen; | |||||
sb->st_blocks = vap->va_bytes / S_BLKSIZE; | |||||
return (0); | |||||
} | } | ||||
/* | /* | ||||
* File table vnode ioctl routine. | * File table vnode ioctl routine. | ||||
*/ | */ | ||||
static int | static int | ||||
vn_ioctl(struct file *fp, u_long com, void *data, struct ucred *active_cred, | vn_ioctl(struct file *fp, u_long com, void *data, struct ucred *active_cred, | ||||
struct thread *td) | struct thread *td) | ||||
▲ Show 20 Lines • Show All 1,693 Lines • Show Last 20 Lines |