#include <rev_endian_fs.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/resourcevar.h>
#include <sys/kernel.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/buf.h>
#include <sys/proc.h>
#include <sys/conf.h>
#include <sys/mount.h>
#include <sys/vnode.h>
#include <sys/malloc.h>
#include <sys/ubc.h>
#include <sys/vm.h>
#include <vfs/vfs_support.h>
#include <miscfs/specfs/specdev.h>
#include <miscfs/fifofs/fifo.h>
#include <ufs/ufs/lockf.h>
#include <ufs/ufs/quota.h>
#include <ufs/ufs/inode.h>
#include <ufs/ufs/dir.h>
#include <ufs/ufs/ufsmount.h>
#include <ufs/ufs/ufs_extern.h>
#include <ufs/ffs/fs.h>
#include <ufs/ffs/ffs_extern.h>
#if REV_ENDIAN_FS
#include <ufs/ufs/ufs_byte_order.h>
#include <architecture/byte_order.h>
#endif
#define VOPFUNC int (*)(void *)
int (**ffs_vnodeop_p)(void *);
struct vnodeopv_entry_desc ffs_vnodeop_entries[] = {
{ &vop_default_desc, (VOPFUNC)vn_default_error },
{ &vop_lookup_desc, (VOPFUNC)ufs_lookup },
{ &vop_create_desc, (VOPFUNC)ufs_create },
{ &vop_whiteout_desc, (VOPFUNC)ufs_whiteout },
{ &vop_mknod_desc, (VOPFUNC)ufs_mknod },
{ &vop_open_desc, (VOPFUNC)ufs_open },
{ &vop_close_desc, (VOPFUNC)ufs_close },
{ &vop_access_desc, (VOPFUNC)ufs_access },
{ &vop_getattr_desc, (VOPFUNC)ufs_getattr },
{ &vop_setattr_desc, (VOPFUNC)ufs_setattr },
{ &vop_read_desc, (VOPFUNC)ffs_read },
{ &vop_write_desc, (VOPFUNC)ffs_write },
{ &vop_lease_desc, (VOPFUNC)ufs_lease_check },
{ &vop_ioctl_desc, (VOPFUNC)ufs_ioctl },
{ &vop_select_desc, (VOPFUNC)ufs_select },
{ &vop_revoke_desc, (VOPFUNC)ufs_revoke },
{ &vop_mmap_desc, (VOPFUNC)ufs_mmap },
{ &vop_fsync_desc, (VOPFUNC)ffs_fsync },
{ &vop_seek_desc, (VOPFUNC)ufs_seek },
{ &vop_remove_desc, (VOPFUNC)ufs_remove },
{ &vop_link_desc, (VOPFUNC)ufs_link },
{ &vop_rename_desc, (VOPFUNC)ufs_rename },
{ &vop_mkdir_desc, (VOPFUNC)ufs_mkdir },
{ &vop_rmdir_desc, (VOPFUNC)ufs_rmdir },
{ &vop_symlink_desc, (VOPFUNC)ufs_symlink },
{ &vop_readdir_desc, (VOPFUNC)ufs_readdir },
{ &vop_readlink_desc, (VOPFUNC)ufs_readlink },
{ &vop_abortop_desc, (VOPFUNC)ufs_abortop },
{ &vop_inactive_desc, (VOPFUNC)ufs_inactive },
{ &vop_reclaim_desc, (VOPFUNC)ffs_reclaim },
{ &vop_lock_desc, (VOPFUNC)ufs_lock },
{ &vop_unlock_desc, (VOPFUNC)ufs_unlock },
{ &vop_bmap_desc, (VOPFUNC)ufs_bmap },
{ &vop_strategy_desc, (VOPFUNC)ufs_strategy },
{ &vop_print_desc, (VOPFUNC)ufs_print },
{ &vop_islocked_desc, (VOPFUNC)ufs_islocked },
{ &vop_pathconf_desc, (VOPFUNC)ufs_pathconf },
{ &vop_advlock_desc, (VOPFUNC)ufs_advlock },
{ &vop_blkatoff_desc, (VOPFUNC)ffs_blkatoff },
{ &vop_valloc_desc, (VOPFUNC)ffs_valloc },
{ &vop_reallocblks_desc, (VOPFUNC)ffs_reallocblks },
{ &vop_vfree_desc, (VOPFUNC)ffs_vfree },
{ &vop_truncate_desc, (VOPFUNC)ffs_truncate },
{ &vop_update_desc, (VOPFUNC)ffs_update },
{ &vop_bwrite_desc, (VOPFUNC)vn_bwrite },
{ &vop_pagein_desc, (VOPFUNC)ffs_pagein },
{ &vop_pageout_desc, (VOPFUNC)ffs_pageout },
{ &vop_copyfile_desc, (VOPFUNC)err_copyfile },
{ &vop_blktooff_desc, (VOPFUNC)ffs_blktooff },
{ &vop_offtoblk_desc, (VOPFUNC)ffs_offtoblk },
{ &vop_cmap_desc, (VOPFUNC)ufs_cmap },
{ (struct vnodeop_desc*)NULL, (int(*)())NULL }
};
struct vnodeopv_desc ffs_vnodeop_opv_desc =
{ &ffs_vnodeop_p, ffs_vnodeop_entries };
int (**ffs_specop_p)(void *);
struct vnodeopv_entry_desc ffs_specop_entries[] = {
{ &vop_default_desc, (VOPFUNC)vn_default_error },
{ &vop_lookup_desc, (VOPFUNC)spec_lookup },
{ &vop_create_desc, (VOPFUNC)spec_create },
{ &vop_mknod_desc, (VOPFUNC)spec_mknod },
{ &vop_open_desc, (VOPFUNC)spec_open },
{ &vop_close_desc, (VOPFUNC)ufsspec_close },
{ &vop_access_desc, (VOPFUNC)ufs_access },
{ &vop_getattr_desc, (VOPFUNC)ufs_getattr },
{ &vop_setattr_desc, (VOPFUNC)ufs_setattr },
{ &vop_read_desc, (VOPFUNC)ufsspec_read },
{ &vop_write_desc, (VOPFUNC)ufsspec_write },
{ &vop_lease_desc, (VOPFUNC)spec_lease_check },
{ &vop_ioctl_desc, (VOPFUNC)spec_ioctl },
{ &vop_select_desc, (VOPFUNC)spec_select },
{ &vop_revoke_desc, (VOPFUNC)spec_revoke },
{ &vop_mmap_desc, (VOPFUNC)spec_mmap },
{ &vop_fsync_desc, (VOPFUNC)ffs_fsync },
{ &vop_seek_desc, (VOPFUNC)spec_seek },
{ &vop_remove_desc, (VOPFUNC)spec_remove },
{ &vop_link_desc, (VOPFUNC)spec_link },
{ &vop_rename_desc, (VOPFUNC)spec_rename },
{ &vop_mkdir_desc, (VOPFUNC)spec_mkdir },
{ &vop_rmdir_desc, (VOPFUNC)spec_rmdir },
{ &vop_symlink_desc, (VOPFUNC)spec_symlink },
{ &vop_readdir_desc, (VOPFUNC)spec_readdir },
{ &vop_readlink_desc, (VOPFUNC)spec_readlink },
{ &vop_abortop_desc, (VOPFUNC)spec_abortop },
{ &vop_inactive_desc, (VOPFUNC)ufs_inactive },
{ &vop_reclaim_desc, (VOPFUNC)ffs_reclaim },
{ &vop_lock_desc, (VOPFUNC)ufs_lock },
{ &vop_unlock_desc, (VOPFUNC)ufs_unlock },
{ &vop_bmap_desc, (VOPFUNC)spec_bmap },
{ &vop_strategy_desc, (VOPFUNC)spec_strategy },
{ &vop_print_desc, (VOPFUNC)ufs_print },
{ &vop_islocked_desc, (VOPFUNC)ufs_islocked },
{ &vop_pathconf_desc, (VOPFUNC)spec_pathconf },
{ &vop_advlock_desc, (VOPFUNC)spec_advlock },
{ &vop_blkatoff_desc, (VOPFUNC)spec_blkatoff },
{ &vop_valloc_desc, (VOPFUNC)spec_valloc },
{ &vop_reallocblks_desc, (VOPFUNC)spec_reallocblks },
{ &vop_vfree_desc, (VOPFUNC)ffs_vfree },
{ &vop_truncate_desc, (VOPFUNC)spec_truncate },
{ &vop_update_desc, (VOPFUNC)ffs_update },
{ &vop_bwrite_desc, (VOPFUNC)vn_bwrite },
{ &vop_devblocksize_desc, (VOPFUNC)spec_devblocksize },
{ &vop_pagein_desc, (VOPFUNC)ffs_pagein },
{ &vop_pageout_desc, (VOPFUNC)ffs_pageout },
{ &vop_copyfile_desc, (VOPFUNC)err_copyfile },
{ &vop_blktooff_desc, (VOPFUNC)ffs_blktooff },
{ &vop_offtoblk_desc, (VOPFUNC)ffs_offtoblk },
{ &vop_cmap_desc, (VOPFUNC)spec_cmap },
{ (struct vnodeop_desc*)NULL, (int(*)())NULL }
};
struct vnodeopv_desc ffs_specop_opv_desc =
{ &ffs_specop_p, ffs_specop_entries };
#if FIFO
int (**ffs_fifoop_p)(void *);
struct vnodeopv_entry_desc ffs_fifoop_entries[] = {
{ &vop_default_desc, (VOPFUNC)vn_default_error },
{ &vop_lookup_desc, (VOPFUNC)fifo_lookup },
{ &vop_create_desc, (VOPFUNC)fifo_create },
{ &vop_mknod_desc, (VOPFUNC)fifo_mknod },
{ &vop_open_desc, (VOPFUNC)fifo_open },
{ &vop_close_desc, (VOPFUNC)ufsfifo_close },
{ &vop_access_desc, (VOPFUNC)ufs_access },
{ &vop_getattr_desc, (VOPFUNC)ufs_getattr },
{ &vop_setattr_desc, (VOPFUNC)ufs_setattr },
{ &vop_read_desc, (VOPFUNC)ufsfifo_read },
{ &vop_write_desc, (VOPFUNC)ufsfifo_write },
{ &vop_lease_desc, (VOPFUNC)fifo_lease_check },
{ &vop_ioctl_desc, (VOPFUNC)fifo_ioctl },
{ &vop_select_desc, (VOPFUNC)fifo_select },
{ &vop_revoke_desc, (VOPFUNC)fifo_revoke },
{ &vop_mmap_desc, (VOPFUNC)fifo_mmap },
{ &vop_fsync_desc, (VOPFUNC)ffs_fsync },
{ &vop_seek_desc, (VOPFUNC)fifo_seek },
{ &vop_remove_desc, (VOPFUNC)fifo_remove },
{ &vop_link_desc, (VOPFUNC)fifo_link },
{ &vop_rename_desc, (VOPFUNC)fifo_rename },
{ &vop_mkdir_desc, (VOPFUNC)fifo_mkdir },
{ &vop_rmdir_desc, (VOPFUNC)fifo_rmdir },
{ &vop_symlink_desc, (VOPFUNC)fifo_symlink },
{ &vop_readdir_desc, (VOPFUNC)fifo_readdir },
{ &vop_readlink_desc, (VOPFUNC)fifo_readlink },
{ &vop_abortop_desc, (VOPFUNC)fifo_abortop },
{ &vop_inactive_desc, (VOPFUNC)ufs_inactive },
{ &vop_reclaim_desc, (VOPFUNC)ffs_reclaim },
{ &vop_lock_desc, (VOPFUNC)ufs_lock },
{ &vop_unlock_desc, (VOPFUNC)ufs_unlock },
{ &vop_bmap_desc, (VOPFUNC)fifo_bmap },
{ &vop_strategy_desc, (VOPFUNC)fifo_strategy },
{ &vop_print_desc, (VOPFUNC)ufs_print },
{ &vop_islocked_desc, (VOPFUNC)ufs_islocked },
{ &vop_pathconf_desc, (VOPFUNC)fifo_pathconf },
{ &vop_advlock_desc, (VOPFUNC)fifo_advlock },
{ &vop_blkatoff_desc, (VOPFUNC)fifo_blkatoff },
{ &vop_valloc_desc, (VOPFUNC)fifo_valloc },
{ &vop_reallocblks_desc, (VOPFUNC)fifo_reallocblks },
{ &vop_vfree_desc, (VOPFUNC)ffs_vfree },
{ &vop_truncate_desc, (VOPFUNC)fifo_truncate },
{ &vop_update_desc, (VOPFUNC)ffs_update },
{ &vop_bwrite_desc, (VOPFUNC)vn_bwrite },
{ &vop_pagein_desc, (VOPFUNC)ffs_pagein },
{ &vop_pageout_desc, (VOPFUNC)ffs_pageout },
{ &vop_copyfile_desc, (VOPFUNC)err_copyfile },
{ &vop_blktooff_desc, (VOPFUNC)ffs_blktooff },
{ &vop_offtoblk_desc, (VOPFUNC)ffs_offtoblk },
{ &vop_cmap_desc, (VOPFUNC)ufs_cmap },
{ (struct vnodeop_desc*)NULL, (int(*)())NULL }
};
struct vnodeopv_desc ffs_fifoop_opv_desc =
{ &ffs_fifoop_p, ffs_fifoop_entries };
#endif
int doclusterread = 0;
int doclusterwrite = 0;
#include <ufs/ufs/ufs_readwrite.c>
int
ffs_fsync(ap)
struct vop_fsync_args *ap;
{
register struct vnode *vp = ap->a_vp;
register struct buf *bp;
struct timeval tv;
struct buf *nbp;
int s;
struct inode *ip = VTOI(vp);
cluster_push(vp);
loop:
s = splbio();
for (bp = vp->v_dirtyblkhd.lh_first; bp; bp = nbp) {
nbp = bp->b_vnbufs.le_next;
if ((bp->b_flags & B_BUSY))
continue;
if ((bp->b_flags & B_DELWRI) == 0)
panic("ffs_fsync: not dirty");
bremfree(bp);
bp->b_flags |= B_BUSY;
splx(s);
if (bp->b_vp == vp || ap->a_waitfor == MNT_NOWAIT)
(void) bawrite(bp);
else
(void) bwrite(bp);
goto loop;
}
if (vp->v_flag & VHASDIRTY)
ubc_pushdirty(vp);
if (ap->a_waitfor == MNT_WAIT) {
while (vp->v_numoutput) {
vp->v_flag |= VBWAIT;
tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1, "ffs_fsync", 0);
}
if (vp->v_dirtyblkhd.lh_first || (vp->v_flag & VHASDIRTY)) {
vprint("ffs_fsync: dirty", vp);
splx(s);
goto loop;
}
}
splx(s);
tv = time;
return (VOP_UPDATE(ap->a_vp, &tv, &tv, ap->a_waitfor == MNT_WAIT));
}
int
ffs_reclaim(ap)
struct vop_reclaim_args *ap;
{
register struct vnode *vp = ap->a_vp;
int error;
if (error = ufs_reclaim(vp, ap->a_p))
return (error);
FREE_ZONE(vp->v_data, sizeof (struct inode),
VFSTOUFS(vp->v_mount)->um_devvp->v_tag == VT_MFS ?
M_MFSNODE : M_FFSNODE);
vp->v_data = NULL;
return (0);
}
int
ffs_blktooff(ap)
struct vop_blktooff_args *ap;
{
register struct inode *ip;
register FS *fs;
ufs_daddr_t bn;
if (ap->a_vp == NULL)
return (EINVAL);
ip = VTOI(ap->a_vp);
fs = ip->I_FS;
bn = ap->a_lblkno;
if ((long)bn < 0) {
panic("-ve blkno in ffs_blktooff");
bn = -(long)bn;
}
*ap->a_offset = (off_t)lblktosize(fs, bn);
return (0);
}
int
ffs_offtoblk(ap)
struct vop_offtoblk_args *ap;
{
register struct inode *ip;
register FS *fs;
if (ap->a_vp == NULL)
return (EINVAL);
ip = VTOI(ap->a_vp);
fs = ip->I_FS;
*ap->a_lblkno = (daddr_t)lblkno(fs, ap->a_offset);
return (0);
}