int v7fs_fsync(void *v) { struct vop_fsync_args /* { struct vnode *a_vp; kauth_cred_t a_cred; int a_flags; off_t offlo; off_t offhi; } */ *a = v; struct vnode *vp = a->a_vp; int error, wait; DPRINTF("%p\n", a->a_vp); if (a->a_flags & FSYNC_CACHE) { return EOPNOTSUPP; } wait = (a->a_flags & FSYNC_WAIT); error = vflushbuf(vp, a->a_flags); if (error == 0 && (a->a_flags & FSYNC_DATAONLY) == 0) error = v7fs_update(vp, NULL, NULL, wait ? UPDATE_WAIT : 0); return error; }
/* * Flush the blocks of a file to disk. * * This function is worthless for vnodes that represent directories. Maybe we * could just do a sync if they try an fsync on a directory file. */ int msdosfs_fsync(void *v) { struct vop_fsync_args *ap = v; struct vnode *vp = ap->a_vp; vflushbuf(vp, ap->a_waitfor == MNT_WAIT); return (deupdat(VTODE(vp), ap->a_waitfor == MNT_WAIT)); }
/* ARGSUSED */ int ext2fs_fsync(void *v) { struct vop_fsync_args *ap = v; struct vnode *vp = ap->a_vp; vflushbuf(vp, ap->a_waitfor == MNT_WAIT); return (ext2fs_update(VTOI(ap->a_vp), ap->a_waitfor == MNT_WAIT)); }
/* * Flush the blocks of a file to disk. * * This function is worthless for vnodes that represent directories. Maybe we * could just do a sync if they try an fsync on a directory file. */ static int ntfs_fsync(void *v) { struct vop_fsync_args /* { struct vnode *a_vp; kauth_cred_t a_cred; int a_flags; off_t offlo; off_t offhi; } */ *ap = v; struct vnode *vp = ap->a_vp; if (ap->a_flags & FSYNC_CACHE) { return EOPNOTSUPP; } return vflushbuf(vp, ap->a_flags); }
/* ARGSUSED */ int ffs_full_fsync(struct vnode *vp, int flags) { int error, i, uflags; struct mount *mp; KASSERT(vp->v_tag == VT_UFS); KASSERT(VTOI(vp) != NULL); KASSERT(vp->v_type != VCHR && vp->v_type != VBLK); error = 0; uflags = UPDATE_CLOSE | ((flags & FSYNC_WAIT) ? UPDATE_WAIT : 0); mp = vp->v_mount; /* * Flush all dirty data associated with the vnode. */ if (vp->v_type == VREG) { int pflags = PGO_ALLPAGES | PGO_CLEANIT; if ((flags & FSYNC_WAIT)) pflags |= PGO_SYNCIO; if (fstrans_getstate(mp) == FSTRANS_SUSPENDING) pflags |= PGO_FREE; mutex_enter(vp->v_interlock); error = VOP_PUTPAGES(vp, 0, 0, pflags); if (error) return error; } #ifdef WAPBL if (mp && mp->mnt_wapbl) { /* * Don't bother writing out metadata if the syncer is * making the request. We will let the sync vnode * write it out in a single burst through a call to * VFS_SYNC(). */ if ((flags & (FSYNC_DATAONLY | FSYNC_LAZY)) != 0) return 0; if ((VTOI(vp)->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE | IN_MODIFY | IN_MODIFIED | IN_ACCESSED)) != 0) { error = UFS_WAPBL_BEGIN(mp); if (error) return error; error = ffs_update(vp, NULL, NULL, uflags); UFS_WAPBL_END(mp); } if (error || (flags & FSYNC_NOLOG) != 0) return error; /* * Don't flush the log if the vnode being flushed * contains no dirty buffers that could be in the log. */ if (!LIST_EMPTY(&vp->v_dirtyblkhd)) { error = wapbl_flush(mp->mnt_wapbl, 0); if (error) return error; } if ((flags & FSYNC_WAIT) != 0) { mutex_enter(vp->v_interlock); while (vp->v_numoutput != 0) cv_wait(&vp->v_cv, vp->v_interlock); mutex_exit(vp->v_interlock); } return error; } #endif /* WAPBL */ error = vflushbuf(vp, (flags & FSYNC_WAIT) != 0); if (error == 0) error = ffs_update(vp, NULL, NULL, uflags); if (error == 0 && (flags & FSYNC_CACHE) != 0) { i = 1; (void)VOP_IOCTL(VTOI(vp)->i_devvp, DIOCCACHESYNC, &i, FWRITE, kauth_cred_get()); } return error; }