version 1.470.4.4, 2020/04/21 18:42:42 |
version 1.471, 2019/01/01 10:06:54 |
|
|
/* $NetBSD$ */ |
/* $NetBSD$ */ |
|
|
/*- |
/*- |
* Copyright (c) 1997, 1998, 2004, 2005, 2007, 2008, 2019, 2020 |
* Copyright (c) 1997, 1998, 2004, 2005, 2007, 2008 The NetBSD Foundation, Inc. |
* The NetBSD Foundation, Inc. |
|
* All rights reserved. |
* All rights reserved. |
* |
* |
* This code is derived from software contributed to The NetBSD Foundation |
* This code is derived from software contributed to The NetBSD Foundation |
Line 155 vinvalbuf(struct vnode *vp, int flags, k |
|
Line 154 vinvalbuf(struct vnode *vp, int flags, k |
|
(flags & V_SAVE ? PGO_CLEANIT | PGO_RECLAIM : 0); |
(flags & V_SAVE ? PGO_CLEANIT | PGO_RECLAIM : 0); |
|
|
/* XXXUBC this doesn't look at flags or slp* */ |
/* XXXUBC this doesn't look at flags or slp* */ |
rw_enter(vp->v_uobj.vmobjlock, RW_WRITER); |
mutex_enter(vp->v_interlock); |
error = VOP_PUTPAGES(vp, 0, 0, flushflags); |
error = VOP_PUTPAGES(vp, 0, 0, flushflags); |
if (error) { |
if (error) { |
return error; |
return error; |
Line 234 vtruncbuf(struct vnode *vp, daddr_t lbn, |
|
Line 233 vtruncbuf(struct vnode *vp, daddr_t lbn, |
|
voff_t off; |
voff_t off; |
|
|
off = round_page((voff_t)lbn << vp->v_mount->mnt_fs_bshift); |
off = round_page((voff_t)lbn << vp->v_mount->mnt_fs_bshift); |
rw_enter(vp->v_uobj.vmobjlock, RW_WRITER); |
mutex_enter(vp->v_interlock); |
error = VOP_PUTPAGES(vp, off, 0, PGO_FREE | PGO_SYNCIO); |
error = VOP_PUTPAGES(vp, off, 0, PGO_FREE | PGO_SYNCIO); |
if (error) { |
if (error) { |
return error; |
return error; |
Line 292 vflushbuf(struct vnode *vp, int flags) |
|
Line 291 vflushbuf(struct vnode *vp, int flags) |
|
pflags = PGO_CLEANIT | PGO_ALLPAGES | |
pflags = PGO_CLEANIT | PGO_ALLPAGES | |
(sync ? PGO_SYNCIO : 0) | |
(sync ? PGO_SYNCIO : 0) | |
((flags & FSYNC_LAZY) ? PGO_LAZY : 0); |
((flags & FSYNC_LAZY) ? PGO_LAZY : 0); |
rw_enter(vp->v_uobj.vmobjlock, RW_WRITER); |
mutex_enter(vp->v_interlock); |
(void) VOP_PUTPAGES(vp, 0, 0, pflags); |
(void) VOP_PUTPAGES(vp, 0, 0, pflags); |
|
|
loop: |
loop: |
Line 421 brelvp(struct buf *bp) |
|
Line 420 brelvp(struct buf *bp) |
|
if (LIST_NEXT(bp, b_vnbufs) != NOLIST) |
if (LIST_NEXT(bp, b_vnbufs) != NOLIST) |
bufremvn(bp); |
bufremvn(bp); |
|
|
if ((vp->v_iflag & (VI_ONWORKLST | VI_PAGES)) == VI_ONWORKLST && |
if (vp->v_uobj.uo_npages == 0 && (vp->v_iflag & VI_ONWORKLST) && |
LIST_FIRST(&vp->v_dirtyblkhd) == NULL) |
LIST_FIRST(&vp->v_dirtyblkhd) == NULL) { |
|
vp->v_iflag &= ~VI_WRMAPDIRTY; |
vn_syncer_remove_from_worklist(vp); |
vn_syncer_remove_from_worklist(vp); |
|
} |
|
|
bp->b_objlock = &buffer_lock; |
bp->b_objlock = &buffer_lock; |
bp->b_vp = NULL; |
bp->b_vp = NULL; |
Line 459 reassignbuf(struct buf *bp, struct vnode |
|
Line 460 reassignbuf(struct buf *bp, struct vnode |
|
*/ |
*/ |
if ((bp->b_oflags & BO_DELWRI) == 0) { |
if ((bp->b_oflags & BO_DELWRI) == 0) { |
listheadp = &vp->v_cleanblkhd; |
listheadp = &vp->v_cleanblkhd; |
if ((vp->v_iflag & (VI_ONWORKLST | VI_PAGES)) == |
if (vp->v_uobj.uo_npages == 0 && |
VI_ONWORKLST && |
(vp->v_iflag & VI_ONWORKLST) && |
LIST_FIRST(&vp->v_dirtyblkhd) == NULL) |
LIST_FIRST(&vp->v_dirtyblkhd) == NULL) { |
|
vp->v_iflag &= ~VI_WRMAPDIRTY; |
vn_syncer_remove_from_worklist(vp); |
vn_syncer_remove_from_worklist(vp); |
|
} |
} else { |
} else { |
listheadp = &vp->v_dirtyblkhd; |
listheadp = &vp->v_dirtyblkhd; |
if ((vp->v_iflag & VI_ONWORKLST) == 0) { |
if ((vp->v_iflag & VI_ONWORKLST) == 0) { |
Line 664 vn_syncer_remove_from_worklist(struct vn |
|
Line 667 vn_syncer_remove_from_worklist(struct vn |
|
|
|
KASSERT(mutex_owned(vp->v_interlock)); |
KASSERT(mutex_owned(vp->v_interlock)); |
|
|
|
mutex_enter(&syncer_data_lock); |
if (vp->v_iflag & VI_ONWORKLST) { |
if (vp->v_iflag & VI_ONWORKLST) { |
mutex_enter(&syncer_data_lock); |
|
vp->v_iflag &= ~VI_ONWORKLST; |
vp->v_iflag &= ~VI_ONWORKLST; |
slp = &syncer_workitem_pending[vip->vi_synclist_slot]; |
slp = &syncer_workitem_pending[vip->vi_synclist_slot]; |
TAILQ_REMOVE(slp, vip, vi_synclist); |
TAILQ_REMOVE(slp, vip, vi_synclist); |
mutex_exit(&syncer_data_lock); |
|
} |
} |
|
mutex_exit(&syncer_data_lock); |
} |
} |
|
|
/* |
/* |
Line 682 vfs_syncer_add_to_worklist(struct mount |
|
Line 685 vfs_syncer_add_to_worklist(struct mount |
|
static int start, incr, next; |
static int start, incr, next; |
int vdelay; |
int vdelay; |
|
|
KASSERT(mutex_owned(mp->mnt_updating)); |
KASSERT(mutex_owned(&mp->mnt_updating)); |
KASSERT((mp->mnt_iflag & IMNT_ONWORKLIST) == 0); |
KASSERT((mp->mnt_iflag & IMNT_ONWORKLIST) == 0); |
|
|
/* |
/* |
|
|
vfs_syncer_remove_from_worklist(struct mount *mp) |
vfs_syncer_remove_from_worklist(struct mount *mp) |
{ |
{ |
|
|
KASSERT(mutex_owned(mp->mnt_updating)); |
KASSERT(mutex_owned(&mp->mnt_updating)); |
KASSERT((mp->mnt_iflag & IMNT_ONWORKLIST) != 0); |
KASSERT((mp->mnt_iflag & IMNT_ONWORKLIST) != 0); |
|
|
mp->mnt_iflag &= ~IMNT_ONWORKLIST; |
mp->mnt_iflag &= ~IMNT_ONWORKLIST; |
Line 755 sched_sync(void *arg) |
|
Line 758 sched_sync(void *arg) |
|
{ |
{ |
mount_iterator_t *iter; |
mount_iterator_t *iter; |
synclist_t *slp; |
synclist_t *slp; |
struct vnode_impl *vi; |
|
struct vnode *vp; |
struct vnode *vp; |
struct mount *mp; |
struct mount *mp; |
time_t starttime; |
time_t starttime; |
Line 788 sched_sync(void *arg) |
|
Line 790 sched_sync(void *arg) |
|
if (syncer_delayno >= syncer_last) |
if (syncer_delayno >= syncer_last) |
syncer_delayno = 0; |
syncer_delayno = 0; |
|
|
while ((vi = TAILQ_FIRST(slp)) != NULL) { |
while ((vp = VIMPL_TO_VNODE(TAILQ_FIRST(slp))) != NULL) { |
vp = VIMPL_TO_VNODE(vi); |
|
synced = lazy_sync_vnode(vp); |
synced = lazy_sync_vnode(vp); |
|
|
/* |
/* |
* XXX The vnode may have been recycled, in which |
* XXX The vnode may have been recycled, in which |
* case it may have a new identity. |
* case it may have a new identity. |
*/ |
*/ |
vi = TAILQ_FIRST(slp); |
if (VIMPL_TO_VNODE(TAILQ_FIRST(slp)) == vp) { |
if (vi != NULL && VIMPL_TO_VNODE(vi) == vp) { |
|
/* |
/* |
* Put us back on the worklist. The worklist |
* Put us back on the worklist. The worklist |
* routine will remove us from our current |
* routine will remove us from our current |
Line 1104 vprint_common(struct vnode *vp, const ch |
|
Line 1104 vprint_common(struct vnode *vp, const ch |
|
ARRAY_PRINT(vp->v_type, vnode_types), vp->v_type, |
ARRAY_PRINT(vp->v_type, vnode_types), vp->v_type, |
vp->v_mount, vp->v_mountedhere); |
vp->v_mount, vp->v_mountedhere); |
(*pr)("%susecount %d writecount %d holdcount %d\n", prefix, |
(*pr)("%susecount %d writecount %d holdcount %d\n", prefix, |
vrefcnt(vp), vp->v_writecount, vp->v_holdcnt); |
vp->v_usecount, vp->v_writecount, vp->v_holdcnt); |
(*pr)("%ssize %" PRIx64 " writesize %" PRIx64 " numoutput %d\n", |
(*pr)("%ssize %" PRIx64 " writesize %" PRIx64 " numoutput %d\n", |
prefix, vp->v_size, vp->v_writesize, vp->v_numoutput); |
prefix, vp->v_size, vp->v_writesize, vp->v_numoutput); |
(*pr)("%sdata %p lock %p\n", prefix, vp->v_data, &vip->vi_lock); |
(*pr)("%sdata %p lock %p\n", prefix, vp->v_data, &vip->vi_lock); |
Line 1198 copy_statvfs_info(struct statvfs *sbp, c |
|
Line 1198 copy_statvfs_info(struct statvfs *sbp, c |
|
sizeof(sbp->f_mntonname)); |
sizeof(sbp->f_mntonname)); |
(void)memcpy(sbp->f_mntfromname, mp->mnt_stat.f_mntfromname, |
(void)memcpy(sbp->f_mntfromname, mp->mnt_stat.f_mntfromname, |
sizeof(sbp->f_mntfromname)); |
sizeof(sbp->f_mntfromname)); |
(void)memcpy(sbp->f_mntfromlabel, mp->mnt_stat.f_mntfromlabel, |
|
sizeof(sbp->f_mntfromlabel)); |
|
sbp->f_namemax = mbp->f_namemax; |
sbp->f_namemax = mbp->f_namemax; |
} |
} |
|
|
Line 1211 set_statvfs_info(const char *onp, int uk |
|
Line 1209 set_statvfs_info(const char *onp, int uk |
|
size_t size; |
size_t size; |
struct statvfs *sfs = &mp->mnt_stat; |
struct statvfs *sfs = &mp->mnt_stat; |
int (*fun)(const void *, void *, size_t, size_t *); |
int (*fun)(const void *, void *, size_t, size_t *); |
struct vnode *rvp; |
|
|
|
(void)strlcpy(mp->mnt_stat.f_fstypename, vfsname, |
(void)strlcpy(mp->mnt_stat.f_fstypename, vfsname, |
sizeof(mp->mnt_stat.f_fstypename)); |
sizeof(mp->mnt_stat.f_fstypename)); |
|
|
if (onp) { |
if (onp) { |
|
struct cwdinfo *cwdi = l->l_proc->p_cwdi; |
fun = (ukon == UIO_SYSSPACE) ? copystr : copyinstr; |
fun = (ukon == UIO_SYSSPACE) ? copystr : copyinstr; |
KASSERT(l == curlwp); |
if (cwdi->cwdi_rdir != NULL) { |
rvp = cwdrdir(); |
|
if (rvp != NULL) { |
|
size_t len; |
size_t len; |
char *bp; |
char *bp; |
char *path = PNBUF_GET(); |
char *path = PNBUF_GET(); |
|
|
bp = path + MAXPATHLEN; |
bp = path + MAXPATHLEN; |
*--bp = '\0'; |
*--bp = '\0'; |
error = getcwd_common(rvp, rootvnode, &bp, |
rw_enter(&cwdi->cwdi_lock, RW_READER); |
|
error = getcwd_common(cwdi->cwdi_rdir, rootvnode, &bp, |
path, MAXPATHLEN / 2, 0, l); |
path, MAXPATHLEN / 2, 0, l); |
vrele(rvp); |
rw_exit(&cwdi->cwdi_lock); |
if (error) { |
if (error) { |
PNBUF_PUT(path); |
PNBUF_PUT(path); |
return error; |
return error; |
Line 1347 VFS_UNMOUNT(struct mount *mp, int a) |
|
Line 1344 VFS_UNMOUNT(struct mount *mp, int a) |
|
} |
} |
|
|
int |
int |
VFS_ROOT(struct mount *mp, int lktype, struct vnode **a) |
VFS_ROOT(struct mount *mp, struct vnode **a) |
{ |
{ |
int error; |
int error; |
|
|
if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { |
if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { |
KERNEL_LOCK(1, NULL); |
KERNEL_LOCK(1, NULL); |
} |
} |
error = (*(mp->mnt_op->vfs_root))(mp, lktype, a); |
error = (*(mp->mnt_op->vfs_root))(mp, a); |
if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { |
if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { |
KERNEL_UNLOCK_ONE(NULL); |
KERNEL_UNLOCK_ONE(NULL); |
} |
} |
Line 1411 VFS_SYNC(struct mount *mp, int a, struct |
|
Line 1408 VFS_SYNC(struct mount *mp, int a, struct |
|
} |
} |
|
|
int |
int |
VFS_FHTOVP(struct mount *mp, struct fid *a, int b, struct vnode **c) |
VFS_FHTOVP(struct mount *mp, struct fid *a, struct vnode **b) |
{ |
{ |
int error; |
int error; |
|
|
if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { |
if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { |
KERNEL_LOCK(1, NULL); |
KERNEL_LOCK(1, NULL); |
} |
} |
error = (*(mp->mnt_op->vfs_fhtovp))(mp, a, b, c); |
error = (*(mp->mnt_op->vfs_fhtovp))(mp, a, b); |
if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { |
if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) { |
KERNEL_UNLOCK_ONE(NULL); |
KERNEL_UNLOCK_ONE(NULL); |
} |
} |
Line 1541 vfs_vnode_lock_print(void *vlock, int fu |
|
Line 1538 vfs_vnode_lock_print(void *vlock, int fu |
|
|
|
for (mp = _mountlist_next(NULL); mp; mp = _mountlist_next(mp)) { |
for (mp = _mountlist_next(NULL); mp; mp = _mountlist_next(mp)) { |
TAILQ_FOREACH(vip, &mp->mnt_vnodelist, vi_mntvnodes) { |
TAILQ_FOREACH(vip, &mp->mnt_vnodelist, vi_mntvnodes) { |
if (&vip->vi_lock == vlock || |
if (&vip->vi_lock != vlock) |
VIMPL_TO_VNODE(vip)->v_interlock == vlock) |
continue; |
vfs_vnode_print(VIMPL_TO_VNODE(vip), full, pr); |
vfs_vnode_print(VIMPL_TO_VNODE(vip), full, pr); |
} |
} |
} |
} |
} |
} |
|
|
void |
void |
vfs_mount_print_all(int full, void (*pr)(const char *, ...)) |
|
{ |
|
struct mount *mp; |
|
for (mp = _mountlist_next(NULL); mp; mp = _mountlist_next(mp)) |
|
vfs_mount_print(mp, full, pr); |
|
} |
|
|
|
void |
|
vfs_mount_print(struct mount *mp, int full, void (*pr)(const char *, ...)) |
vfs_mount_print(struct mount *mp, int full, void (*pr)(const char *, ...)) |
{ |
{ |
char sbuf[256]; |
char sbuf[256]; |
Line 1573 vfs_mount_print(struct mount *mp, int fu |
|
Line 1562 vfs_mount_print(struct mount *mp, int fu |
|
snprintb(sbuf, sizeof(sbuf), __IMNT_FLAG_BITS, mp->mnt_iflag); |
snprintb(sbuf, sizeof(sbuf), __IMNT_FLAG_BITS, mp->mnt_iflag); |
(*pr)("iflag = %s\n", sbuf); |
(*pr)("iflag = %s\n", sbuf); |
|
|
(*pr)("refcnt = %d updating @ %p\n", mp->mnt_refcnt, mp->mnt_updating); |
(*pr)("refcnt = %d updating @ %p\n", mp->mnt_refcnt, &mp->mnt_updating); |
|
|
(*pr)("statvfs cache:\n"); |
(*pr)("statvfs cache:\n"); |
(*pr)("\tbsize = %lu\n",mp->mnt_stat.f_bsize); |
(*pr)("\tbsize = %lu\n",mp->mnt_stat.f_bsize); |