Changeset View
Standalone View
sys/fs/tmpfs/tmpfs_vnops.c
Show First 20 Lines • Show All 431 Lines • ▼ Show 20 Lines | out: | ||||
return (error); | return (error); | ||||
} | } | ||||
int | int | ||||
tmpfs_stat(struct vop_stat_args *v) | tmpfs_stat(struct vop_stat_args *v) | ||||
{ | { | ||||
struct vnode *vp = v->a_vp; | struct vnode *vp = v->a_vp; | ||||
struct stat *sb = v->a_sb; | struct stat *sb = v->a_sb; | ||||
vm_object_t obj; | |||||
struct tmpfs_node *node; | struct tmpfs_node *node; | ||||
int error; | int error; | ||||
node = VP_TO_TMPFS_NODE(vp); | node = VP_TO_TMPFS_NODE(vp); | ||||
tmpfs_update_getattr(vp); | tmpfs_update_getattr(vp); | ||||
error = vop_stat_helper_pre(v); | error = vop_stat_helper_pre(v); | ||||
Show All 16 Lines | tmpfs_stat(struct vop_stat_args *v) | ||||
sb->st_ctim.tv_sec = node->tn_ctime.tv_sec; | sb->st_ctim.tv_sec = node->tn_ctime.tv_sec; | ||||
sb->st_ctim.tv_nsec = node->tn_ctime.tv_nsec; | sb->st_ctim.tv_nsec = node->tn_ctime.tv_nsec; | ||||
sb->st_birthtim.tv_sec = node->tn_birthtime.tv_sec; | sb->st_birthtim.tv_sec = node->tn_birthtime.tv_sec; | ||||
sb->st_birthtim.tv_nsec = node->tn_birthtime.tv_nsec; | sb->st_birthtim.tv_nsec = node->tn_birthtime.tv_nsec; | ||||
sb->st_blksize = PAGE_SIZE; | sb->st_blksize = PAGE_SIZE; | ||||
sb->st_flags = node->tn_flags; | sb->st_flags = node->tn_flags; | ||||
sb->st_gen = node->tn_gen; | sb->st_gen = node->tn_gen; | ||||
if (vp->v_type == VREG) { | if (vp->v_type == VREG) { | ||||
obj = node->tn_reg.tn_aobj; | #ifdef __ILP32__ | ||||
sb->st_blocks = (u_quad_t)obj->resident_page_count * PAGE_SIZE; | vm_object_t obj = node->tn_reg.tn_aobj; | ||||
markj: Why can't it use `obj->resident_page_count`? | |||||
Done Inline ActionsBecause some pages could be swapped out. kib: Because some pages could be swapped out. | |||||
Done Inline ActionsSorry, I didn't look carefully at the commit descriptions. But, how do we handle the case where a page is resident and clean, and there is a copy on swap? I think such a page must be counted twice, since the tmpfs mount size includes consumed swap space, but tmpfs does not get any notification from putpages. markj: Sorry, I didn't look carefully at the commit descriptions. But, how do we handle the case where… | |||||
Done Inline ActionsNo, I do not think that it should be counted twice. tn_pages must be equal to the file size - holes size. kib: No, I do not think that it should be counted twice. tn_pages must be equal to the `file size… | |||||
Done Inline ActionsShould shm_stat() similarly avoid reporting holes? markj: Should shm_stat() similarly avoid reporting holes? | |||||
Done Inline ActionsDo you mean s/avoid/start/? I.e., make stat(2) on shmfd report blocks as really allocated pages. In principle this would be a useful addition, which I can do after we agree on this patch. kib: Do you mean s/avoid/start/? I.e., make stat(2) on shmfd report blocks as really allocated pages. | |||||
} else | |||||
Done Inline ActionsIs there any harm in a racy (i.e., unlocked) read? markj: Is there any harm in a racy (i.e., unlocked) read? | |||||
Done Inline ActionsUnlocked read on 32bit machines would give potentially torn value. I am not sure that it worth #ifdef-ing ILP32 there. I can. kib: Unlocked read on 32bit machines would give potentially torn value. I am not sure that it worth… | |||||
Done Inline ActionsI suspect it is a common-enough operation that removing the locking for !ILP32 is worthwhile. markj: I suspect it is a common-enough operation that removing the locking for !ILP32 is worthwhile. | |||||
/* Handle torn read */ | |||||
VM_OBJECT_RLOCK(obj); | |||||
#endif | |||||
sb->st_blocks = ptoa(node->tn_reg.tn_pages); | |||||
#ifdef __ILP32__ | |||||
VM_OBJECT_RUNLOCK(obj); | |||||
#endif | |||||
} else { | |||||
sb->st_blocks = node->tn_size; | sb->st_blocks = node->tn_size; | ||||
} | |||||
sb->st_blocks /= S_BLKSIZE; | sb->st_blocks /= S_BLKSIZE; | ||||
return (vop_stat_helper_post(v, error)); | return (vop_stat_helper_post(v, error)); | ||||
} | } | ||||
int | int | ||||
tmpfs_getattr(struct vop_getattr_args *v) | tmpfs_getattr(struct vop_getattr_args *v) | ||||
{ | { | ||||
struct vnode *vp = v->a_vp; | struct vnode *vp = v->a_vp; | ||||
Show All 16 Lines | tmpfs_getattr(struct vop_getattr_args *v) | ||||
vap->va_blocksize = PAGE_SIZE; | vap->va_blocksize = PAGE_SIZE; | ||||
vap->va_atime = node->tn_atime; | vap->va_atime = node->tn_atime; | ||||
vap->va_mtime = node->tn_mtime; | vap->va_mtime = node->tn_mtime; | ||||
vap->va_ctime = node->tn_ctime; | vap->va_ctime = node->tn_ctime; | ||||
vap->va_birthtime = node->tn_birthtime; | vap->va_birthtime = node->tn_birthtime; | ||||
vap->va_gen = node->tn_gen; | vap->va_gen = node->tn_gen; | ||||
vap->va_flags = node->tn_flags; | vap->va_flags = node->tn_flags; | ||||
vap->va_rdev = (vp->v_type == VBLK || vp->v_type == VCHR) ? | vap->va_rdev = (vp->v_type == VBLK || vp->v_type == VCHR) ? | ||||
node->tn_rdev : NODEV; | node->tn_rdev : NODEV; | ||||
if (vp->v_type == VREG) { | if (vp->v_type == VREG) { | ||||
obj = node->tn_reg.tn_aobj; | obj = node->tn_reg.tn_aobj; | ||||
vap->va_bytes = (u_quad_t)obj->resident_page_count * PAGE_SIZE; | VM_OBJECT_RLOCK(obj); | ||||
} else | vap->va_bytes = ptoa(node->tn_reg.tn_pages); | ||||
VM_OBJECT_RUNLOCK(obj); | |||||
} else { | |||||
vap->va_bytes = node->tn_size; | vap->va_bytes = node->tn_size; | ||||
} | |||||
vap->va_filerev = 0; | vap->va_filerev = 0; | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
tmpfs_setattr(struct vop_setattr_args *v) | tmpfs_setattr(struct vop_setattr_args *v) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 1,488 Lines • Show Last 20 Lines |
Why can't it use obj->resident_page_count?