ufs: use lazy list instead of active list for syncer
Quota code is temporarily regressed to do a full vnode scan. Reviewed by: jeff Tested by: pho (in a larger patch, previous version) Differential Revision: https://reviews.freebsd.org/D22996
This commit is contained in:
parent
57083d2576
commit
80663cadb8
@ -1446,6 +1446,23 @@ sync_doupdate(struct inode *ip)
|
||||
IN_UPDATE)) != 0);
|
||||
}
|
||||
|
||||
static int
|
||||
ffs_sync_lazy_filter(struct vnode *vp, void *arg __unused)
|
||||
{
|
||||
struct inode *ip;
|
||||
|
||||
/*
|
||||
* Flags are safe to access because ->v_data invalidation
|
||||
* is held off by listmtx.
|
||||
*/
|
||||
if (vp->v_type == VNON)
|
||||
return (false);
|
||||
ip = VTOI(vp);
|
||||
if (!sync_doupdate(ip) && (vp->v_iflag & VI_OWEINACT) == 0)
|
||||
return (false);
|
||||
return (true);
|
||||
}
|
||||
|
||||
/*
|
||||
* For a lazy sync, we only care about access times, quotas and the
|
||||
* superblock. Other filesystem changes are already converted to
|
||||
@ -1465,7 +1482,7 @@ ffs_sync_lazy(mp)
|
||||
td = curthread;
|
||||
if ((mp->mnt_flag & MNT_NOATIME) != 0)
|
||||
goto qupdate;
|
||||
MNT_VNODE_FOREACH_ACTIVE(vp, mp, mvp) {
|
||||
MNT_VNODE_FOREACH_LAZY(vp, mp, mvp, ffs_sync_lazy_filter, NULL) {
|
||||
if (vp->v_type == VNON) {
|
||||
VI_UNLOCK(vp);
|
||||
continue;
|
||||
|
@ -113,6 +113,9 @@ static vop_fsync_t ffs_fsync;
|
||||
static vop_getpages_t ffs_getpages;
|
||||
static vop_getpages_async_t ffs_getpages_async;
|
||||
static vop_lock1_t ffs_lock;
|
||||
#ifdef INVARIANTS
|
||||
static vop_unlock_t ffs_unlock_debug;
|
||||
#endif
|
||||
static vop_read_t ffs_read;
|
||||
static vop_write_t ffs_write;
|
||||
static int ffs_extread(struct vnode *vp, struct uio *uio, int ioflag);
|
||||
@ -135,6 +138,9 @@ struct vop_vector ffs_vnodeops1 = {
|
||||
.vop_getpages = ffs_getpages,
|
||||
.vop_getpages_async = ffs_getpages_async,
|
||||
.vop_lock1 = ffs_lock,
|
||||
#ifdef INVARIANTS
|
||||
.vop_unlock = ffs_unlock_debug,
|
||||
#endif
|
||||
.vop_read = ffs_read,
|
||||
.vop_reallocblks = ffs_reallocblks,
|
||||
.vop_write = ffs_write,
|
||||
@ -147,6 +153,9 @@ struct vop_vector ffs_fifoops1 = {
|
||||
.vop_fsync = ffs_fsync,
|
||||
.vop_fdatasync = ffs_fdatasync,
|
||||
.vop_lock1 = ffs_lock,
|
||||
#ifdef INVARIANTS
|
||||
.vop_unlock = ffs_unlock_debug,
|
||||
#endif
|
||||
.vop_vptofh = ffs_vptofh,
|
||||
};
|
||||
VFS_VOP_VECTOR_REGISTER(ffs_fifoops1);
|
||||
@ -159,6 +168,9 @@ struct vop_vector ffs_vnodeops2 = {
|
||||
.vop_getpages = ffs_getpages,
|
||||
.vop_getpages_async = ffs_getpages_async,
|
||||
.vop_lock1 = ffs_lock,
|
||||
#ifdef INVARIANTS
|
||||
.vop_unlock = ffs_unlock_debug,
|
||||
#endif
|
||||
.vop_read = ffs_read,
|
||||
.vop_reallocblks = ffs_reallocblks,
|
||||
.vop_write = ffs_write,
|
||||
@ -177,6 +189,9 @@ struct vop_vector ffs_fifoops2 = {
|
||||
.vop_fsync = ffs_fsync,
|
||||
.vop_fdatasync = ffs_fdatasync,
|
||||
.vop_lock1 = ffs_lock,
|
||||
#ifdef INVARIANTS
|
||||
.vop_unlock = ffs_unlock_debug,
|
||||
#endif
|
||||
.vop_reallocblks = ffs_reallocblks,
|
||||
.vop_strategy = ffsext_strategy,
|
||||
.vop_closeextattr = ffs_closeextattr,
|
||||
@ -463,6 +478,26 @@ ffs_lock(ap)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef INVARIANTS
|
||||
static int
|
||||
ffs_unlock_debug(struct vop_unlock_args *ap)
|
||||
{
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct inode *ip = VTOI(vp);
|
||||
|
||||
if (ip->i_flag & UFS_INODE_FLAG_LAZY_MASK) {
|
||||
if ((vp->v_mflag & VMP_LAZYLIST) == 0) {
|
||||
VI_LOCK(vp);
|
||||
VNASSERT((vp->v_mflag & VMP_LAZYLIST), vp,
|
||||
("%s: modified vnode (%x) not on lazy list",
|
||||
__func__, ip->i_flag));
|
||||
VI_UNLOCK(vp);
|
||||
}
|
||||
}
|
||||
return (VOP_UNLOCK_APV(&ufs_vnodeops, ap));
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
ffs_read_hole(struct uio *uio, long xfersize, long *size)
|
||||
{
|
||||
@ -665,12 +700,8 @@ ffs_read(ap)
|
||||
vfs_bio_brelse(bp, ioflag);
|
||||
|
||||
if ((error == 0 || uio->uio_resid != orig_resid) &&
|
||||
(vp->v_mount->mnt_flag & (MNT_NOATIME | MNT_RDONLY)) == 0 &&
|
||||
(ip->i_flag & IN_ACCESS) == 0) {
|
||||
VI_LOCK(vp);
|
||||
UFS_INODE_SET_FLAG(ip, IN_ACCESS);
|
||||
VI_UNLOCK(vp);
|
||||
}
|
||||
(vp->v_mount->mnt_flag & (MNT_NOATIME | MNT_RDONLY)) == 0)
|
||||
UFS_INODE_SET_FLAG_SHARED(ip, IN_ACCESS);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -138,11 +138,32 @@ struct inode {
|
||||
"\14b12\13is_ufs2\12truncated\11ea_lockwait\10ea_locked" \
|
||||
"\7lazyaccess\6lazymod\5needsync\4modified\3update\2change\1access"
|
||||
|
||||
#define UFS_INODE_FLAG_LAZY_MASK \
|
||||
(IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE | IN_LAZYMOD | IN_LAZYACCESS)
|
||||
|
||||
#define UFS_INODE_SET_FLAG(ip, flags) do { \
|
||||
struct inode *_ip = (ip); \
|
||||
struct vnode *_vp = ITOV(_ip); \
|
||||
int _flags = (flags); \
|
||||
\
|
||||
_ip->i_flag |= _flags; \
|
||||
if (_flags & UFS_INODE_FLAG_LAZY_MASK) \
|
||||
vlazy(_vp); \
|
||||
} while (0)
|
||||
|
||||
#define UFS_INODE_SET_FLAG_SHARED(ip, flags) do { \
|
||||
struct inode *_ip = (ip); \
|
||||
struct vnode *_vp = ITOV(_ip); \
|
||||
int _flags = (flags); \
|
||||
\
|
||||
ASSERT_VI_UNLOCKED(_vp, __func__); \
|
||||
if ((_ip->i_flag & (_flags)) != _flags) { \
|
||||
VI_LOCK(_vp); \
|
||||
_ip->i_flag |= _flags; \
|
||||
if (_flags & UFS_INODE_FLAG_LAZY_MASK) \
|
||||
vlazy(_vp); \
|
||||
VI_UNLOCK(_vp); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define i_dirhash i_un.dirhash
|
||||
|
@ -686,12 +686,9 @@ ufs_markatime(ap)
|
||||
struct vnode *a_vp;
|
||||
} */ *ap;
|
||||
{
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct inode *ip = VTOI(vp);
|
||||
struct inode *ip = VTOI(ap->a_vp);
|
||||
|
||||
VI_LOCK(vp);
|
||||
UFS_INODE_SET_FLAG(ip, IN_ACCESS);
|
||||
VI_UNLOCK(vp);
|
||||
UFS_INODE_SET_FLAG_SHARED(ip, IN_ACCESS);
|
||||
/*
|
||||
* XXXKIB No UFS_UPDATE(ap->a_vp, 0) there.
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user