123405Smckusick /*
263371Sbostic * Copyright (c) 1982, 1986, 1989, 1993
363371Sbostic * The Regents of the University of California. All rights reserved.
423405Smckusick *
544539Sbostic * %sccs.include.redist.c%
637737Smckusick *
7*69416Smckusick * @(#)ffs_vnops.c 8.15 (Berkeley) 05/14/95
823405Smckusick */
937Sbill
1051474Sbostic #include <sys/param.h>
1151474Sbostic #include <sys/systm.h>
1251474Sbostic #include <sys/resourcevar.h>
1351474Sbostic #include <sys/kernel.h>
1451474Sbostic #include <sys/file.h>
1551474Sbostic #include <sys/stat.h>
1651474Sbostic #include <sys/buf.h>
1751474Sbostic #include <sys/proc.h>
1851474Sbostic #include <sys/conf.h>
1951474Sbostic #include <sys/mount.h>
2051474Sbostic #include <sys/vnode.h>
2151474Sbostic #include <sys/malloc.h>
2237Sbill
2353319Smckusick #include <vm/vm.h>
2453319Smckusick
2555032Smckusick #include <miscfs/specfs/specdev.h>
2655032Smckusick #include <miscfs/fifofs/fifo.h>
2755032Smckusick
2851474Sbostic #include <ufs/ufs/lockf.h>
2951474Sbostic #include <ufs/ufs/quota.h>
3051474Sbostic #include <ufs/ufs/inode.h>
3151474Sbostic #include <ufs/ufs/dir.h>
3268131Smckusick #include <ufs/ufs/ufsmount.h>
3351474Sbostic #include <ufs/ufs/ufs_extern.h>
3447571Skarels
3551474Sbostic #include <ufs/ffs/fs.h>
3651474Sbostic #include <ufs/ffs/ffs_extern.h>
376254Sroot
3851474Sbostic /* Global vfs data structures for ufs. */
3953523Sheideman int (**ffs_vnodeop_p)();
4053523Sheideman struct vnodeopv_entry_desc ffs_vnodeop_entries[] = {
4153523Sheideman { &vop_default_desc, vn_default_error },
4253523Sheideman { &vop_lookup_desc, ufs_lookup }, /* lookup */
4353523Sheideman { &vop_create_desc, ufs_create }, /* create */
4467575Spendry { &vop_whiteout_desc, ufs_whiteout }, /* whiteout */
4554014Sheideman { &vop_mknod_desc, ufs_mknod }, /* mknod */
4654014Sheideman { &vop_open_desc, ufs_open }, /* open */
4754014Sheideman { &vop_close_desc, ufs_close }, /* close */
4853523Sheideman { &vop_access_desc, ufs_access }, /* access */
4953523Sheideman { &vop_getattr_desc, ufs_getattr }, /* getattr */
5053523Sheideman { &vop_setattr_desc, ufs_setattr }, /* setattr */
5154014Sheideman { &vop_read_desc, ffs_read }, /* read */
5254014Sheideman { &vop_write_desc, ffs_write }, /* write */
5367642Smckusick { &vop_lease_desc, ufs_lease_check }, /* lease */
5454014Sheideman { &vop_ioctl_desc, ufs_ioctl }, /* ioctl */
5553523Sheideman { &vop_select_desc, ufs_select }, /* select */
5668419Smckusick { &vop_revoke_desc, ufs_revoke }, /* revoke */
5754014Sheideman { &vop_mmap_desc, ufs_mmap }, /* mmap */
5854014Sheideman { &vop_fsync_desc, ffs_fsync }, /* fsync */
5954014Sheideman { &vop_seek_desc, ufs_seek }, /* seek */
6053523Sheideman { &vop_remove_desc, ufs_remove }, /* remove */
6154014Sheideman { &vop_link_desc, ufs_link }, /* link */
6253523Sheideman { &vop_rename_desc, ufs_rename }, /* rename */
6354014Sheideman { &vop_mkdir_desc, ufs_mkdir }, /* mkdir */
6454014Sheideman { &vop_rmdir_desc, ufs_rmdir }, /* rmdir */
6553523Sheideman { &vop_symlink_desc, ufs_symlink }, /* symlink */
6653523Sheideman { &vop_readdir_desc, ufs_readdir }, /* readdir */
6753523Sheideman { &vop_readlink_desc, ufs_readlink }, /* readlink */
6853523Sheideman { &vop_abortop_desc, ufs_abortop }, /* abortop */
6956745Smckusick { &vop_inactive_desc, ufs_inactive }, /* inactive */
7067409Smckusick { &vop_reclaim_desc, ffs_reclaim }, /* reclaim */
7154014Sheideman { &vop_lock_desc, ufs_lock }, /* lock */
7253523Sheideman { &vop_unlock_desc, ufs_unlock }, /* unlock */
7356447Smargo { &vop_bmap_desc, ufs_bmap }, /* bmap */
7453523Sheideman { &vop_strategy_desc, ufs_strategy }, /* strategy */
7554014Sheideman { &vop_print_desc, ufs_print }, /* print */
7653523Sheideman { &vop_islocked_desc, ufs_islocked }, /* islocked */
7760396Smckusick { &vop_pathconf_desc, ufs_pathconf }, /* pathconf */
7853523Sheideman { &vop_advlock_desc, ufs_advlock }, /* advlock */
7953523Sheideman { &vop_blkatoff_desc, ffs_blkatoff }, /* blkatoff */
8053523Sheideman { &vop_valloc_desc, ffs_valloc }, /* valloc */
8165977Smckusick { &vop_reallocblks_desc, ffs_reallocblks }, /* reallocblks */
8254014Sheideman { &vop_vfree_desc, ffs_vfree }, /* vfree */
8353523Sheideman { &vop_truncate_desc, ffs_truncate }, /* truncate */
8453523Sheideman { &vop_update_desc, ffs_update }, /* update */
8553575Sheideman { &vop_bwrite_desc, vn_bwrite },
8653523Sheideman { (struct vnodeop_desc*)NULL, (int(*)())NULL }
8751474Sbostic };
8853523Sheideman struct vnodeopv_desc ffs_vnodeop_opv_desc =
8953523Sheideman { &ffs_vnodeop_p, ffs_vnodeop_entries };
906254Sroot
9153523Sheideman int (**ffs_specop_p)();
9253523Sheideman struct vnodeopv_entry_desc ffs_specop_entries[] = {
9353523Sheideman { &vop_default_desc, vn_default_error },
9453523Sheideman { &vop_lookup_desc, spec_lookup }, /* lookup */
9553523Sheideman { &vop_create_desc, spec_create }, /* create */
9653523Sheideman { &vop_mknod_desc, spec_mknod }, /* mknod */
9754014Sheideman { &vop_open_desc, spec_open }, /* open */
9853523Sheideman { &vop_close_desc, ufsspec_close }, /* close */
9953523Sheideman { &vop_access_desc, ufs_access }, /* access */
10053523Sheideman { &vop_getattr_desc, ufs_getattr }, /* getattr */
10153523Sheideman { &vop_setattr_desc, ufs_setattr }, /* setattr */
10253523Sheideman { &vop_read_desc, ufsspec_read }, /* read */
10353523Sheideman { &vop_write_desc, ufsspec_write }, /* write */
10467642Smckusick { &vop_lease_desc, spec_lease_check }, /* lease */
10553523Sheideman { &vop_ioctl_desc, spec_ioctl }, /* ioctl */
10653523Sheideman { &vop_select_desc, spec_select }, /* select */
10768419Smckusick { &vop_revoke_desc, spec_revoke }, /* revoke */
10854014Sheideman { &vop_mmap_desc, spec_mmap }, /* mmap */
10954462Smckusick { &vop_fsync_desc, ffs_fsync }, /* fsync */
11054014Sheideman { &vop_seek_desc, spec_seek }, /* seek */
11153523Sheideman { &vop_remove_desc, spec_remove }, /* remove */
11254014Sheideman { &vop_link_desc, spec_link }, /* link */
11353523Sheideman { &vop_rename_desc, spec_rename }, /* rename */
11453523Sheideman { &vop_mkdir_desc, spec_mkdir }, /* mkdir */
11553523Sheideman { &vop_rmdir_desc, spec_rmdir }, /* rmdir */
11653523Sheideman { &vop_symlink_desc, spec_symlink }, /* symlink */
11753523Sheideman { &vop_readdir_desc, spec_readdir }, /* readdir */
11853523Sheideman { &vop_readlink_desc, spec_readlink }, /* readlink */
11953523Sheideman { &vop_abortop_desc, spec_abortop }, /* abortop */
12056745Smckusick { &vop_inactive_desc, ufs_inactive }, /* inactive */
12167409Smckusick { &vop_reclaim_desc, ffs_reclaim }, /* reclaim */
12254014Sheideman { &vop_lock_desc, ufs_lock }, /* lock */
12353523Sheideman { &vop_unlock_desc, ufs_unlock }, /* unlock */
12454014Sheideman { &vop_bmap_desc, spec_bmap }, /* bmap */
12553523Sheideman { &vop_strategy_desc, spec_strategy }, /* strategy */
12654014Sheideman { &vop_print_desc, ufs_print }, /* print */
12753523Sheideman { &vop_islocked_desc, ufs_islocked }, /* islocked */
12860396Smckusick { &vop_pathconf_desc, spec_pathconf }, /* pathconf */
12953523Sheideman { &vop_advlock_desc, spec_advlock }, /* advlock */
13053523Sheideman { &vop_blkatoff_desc, spec_blkatoff }, /* blkatoff */
13153523Sheideman { &vop_valloc_desc, spec_valloc }, /* valloc */
13265977Smckusick { &vop_reallocblks_desc, spec_reallocblks }, /* reallocblks */
13354031Smckusick { &vop_vfree_desc, ffs_vfree }, /* vfree */
13453523Sheideman { &vop_truncate_desc, spec_truncate }, /* truncate */
13553523Sheideman { &vop_update_desc, ffs_update }, /* update */
13653575Sheideman { &vop_bwrite_desc, vn_bwrite },
13753523Sheideman { (struct vnodeop_desc*)NULL, (int(*)())NULL }
13851546Smckusick };
13953523Sheideman struct vnodeopv_desc ffs_specop_opv_desc =
14053523Sheideman { &ffs_specop_p, ffs_specop_entries };
14151546Smckusick
14251546Smckusick #ifdef FIFO
14353523Sheideman int (**ffs_fifoop_p)();
14453523Sheideman struct vnodeopv_entry_desc ffs_fifoop_entries[] = {
14553523Sheideman { &vop_default_desc, vn_default_error },
14653523Sheideman { &vop_lookup_desc, fifo_lookup }, /* lookup */
14753523Sheideman { &vop_create_desc, fifo_create }, /* create */
14853523Sheideman { &vop_mknod_desc, fifo_mknod }, /* mknod */
14954014Sheideman { &vop_open_desc, fifo_open }, /* open */
15053523Sheideman { &vop_close_desc, ufsfifo_close }, /* close */
15153523Sheideman { &vop_access_desc, ufs_access }, /* access */
15253523Sheideman { &vop_getattr_desc, ufs_getattr }, /* getattr */
15353523Sheideman { &vop_setattr_desc, ufs_setattr }, /* setattr */
15453523Sheideman { &vop_read_desc, ufsfifo_read }, /* read */
15553523Sheideman { &vop_write_desc, ufsfifo_write }, /* write */
15667642Smckusick { &vop_lease_desc, fifo_lease_check }, /* lease */
15753523Sheideman { &vop_ioctl_desc, fifo_ioctl }, /* ioctl */
15853523Sheideman { &vop_select_desc, fifo_select }, /* select */
15968419Smckusick { &vop_revoke_desc, fifo_revoke }, /* revoke */
16054014Sheideman { &vop_mmap_desc, fifo_mmap }, /* mmap */
16154462Smckusick { &vop_fsync_desc, ffs_fsync }, /* fsync */
16254014Sheideman { &vop_seek_desc, fifo_seek }, /* seek */
16353523Sheideman { &vop_remove_desc, fifo_remove }, /* remove */
16454014Sheideman { &vop_link_desc, fifo_link }, /* link */
16553523Sheideman { &vop_rename_desc, fifo_rename }, /* rename */
16653523Sheideman { &vop_mkdir_desc, fifo_mkdir }, /* mkdir */
16753523Sheideman { &vop_rmdir_desc, fifo_rmdir }, /* rmdir */
16853523Sheideman { &vop_symlink_desc, fifo_symlink }, /* symlink */
16953523Sheideman { &vop_readdir_desc, fifo_readdir }, /* readdir */
17053523Sheideman { &vop_readlink_desc, fifo_readlink }, /* readlink */
17153523Sheideman { &vop_abortop_desc, fifo_abortop }, /* abortop */
17256745Smckusick { &vop_inactive_desc, ufs_inactive }, /* inactive */
17367409Smckusick { &vop_reclaim_desc, ffs_reclaim }, /* reclaim */
17454014Sheideman { &vop_lock_desc, ufs_lock }, /* lock */
17553523Sheideman { &vop_unlock_desc, ufs_unlock }, /* unlock */
17654014Sheideman { &vop_bmap_desc, fifo_bmap }, /* bmap */
17753523Sheideman { &vop_strategy_desc, fifo_strategy }, /* strategy */
17854014Sheideman { &vop_print_desc, ufs_print }, /* print */
17953523Sheideman { &vop_islocked_desc, ufs_islocked }, /* islocked */
18060396Smckusick { &vop_pathconf_desc, fifo_pathconf }, /* pathconf */
18153523Sheideman { &vop_advlock_desc, fifo_advlock }, /* advlock */
18253523Sheideman { &vop_blkatoff_desc, fifo_blkatoff }, /* blkatoff */
18353523Sheideman { &vop_valloc_desc, fifo_valloc }, /* valloc */
18465977Smckusick { &vop_reallocblks_desc, fifo_reallocblks }, /* reallocblks */
18554031Smckusick { &vop_vfree_desc, ffs_vfree }, /* vfree */
18653523Sheideman { &vop_truncate_desc, fifo_truncate }, /* truncate */
18753523Sheideman { &vop_update_desc, ffs_update }, /* update */
18853575Sheideman { &vop_bwrite_desc, vn_bwrite },
18953523Sheideman { (struct vnodeop_desc*)NULL, (int(*)())NULL }
19051546Smckusick };
19153523Sheideman struct vnodeopv_desc ffs_fifoop_opv_desc =
19253523Sheideman { &ffs_fifoop_p, ffs_fifoop_entries };
19351546Smckusick #endif /* FIFO */
19451546Smckusick
19557416Smckusick /*
19657416Smckusick * Enabling cluster read/write operations.
19757416Smckusick */
19859158Smckusick int doclusterread = 1;
19959158Smckusick int doclusterwrite = 1;
2006254Sroot
20164408Smckusick #include <ufs/ufs/ufs_readwrite.c>
20239608Smckusick
20339608Smckusick /*
20437737Smckusick * Synch an open file.
2059167Ssam */
20637737Smckusick /* ARGSUSED */
20751474Sbostic int
ffs_fsync(ap)20853869Smckusick ffs_fsync(ap)
20954462Smckusick struct vop_fsync_args /* {
21054462Smckusick struct vnode *a_vp;
21154462Smckusick struct ucred *a_cred;
21254462Smckusick int a_waitfor;
21354462Smckusick struct proc *a_p;
21454462Smckusick } */ *ap;
2157701Ssam {
21654462Smckusick register struct vnode *vp = ap->a_vp;
21754462Smckusick register struct buf *bp;
21854763Smckusick struct timeval tv;
21954462Smckusick struct buf *nbp;
22054462Smckusick int s;
2217701Ssam
22254462Smckusick /*
22354462Smckusick * Flush all dirty buffers associated with a vnode.
22454462Smckusick */
22554462Smckusick loop:
22654462Smckusick s = splbio();
22765237Smckusick for (bp = vp->v_dirtyblkhd.lh_first; bp; bp = nbp) {
22865237Smckusick nbp = bp->b_vnbufs.le_next;
22954462Smckusick if ((bp->b_flags & B_BUSY))
23054462Smckusick continue;
23154462Smckusick if ((bp->b_flags & B_DELWRI) == 0)
23254462Smckusick panic("ffs_fsync: not dirty");
23354462Smckusick bremfree(bp);
23454462Smckusick bp->b_flags |= B_BUSY;
23554462Smckusick splx(s);
23654462Smckusick /*
23754462Smckusick * Wait for I/O associated with indirect blocks to complete,
23854462Smckusick * since there is no way to quickly wait for them below.
23954462Smckusick */
24054462Smckusick if (bp->b_vp == vp || ap->a_waitfor == MNT_NOWAIT)
24154462Smckusick (void) bawrite(bp);
24254462Smckusick else
24354462Smckusick (void) bwrite(bp);
24454462Smckusick goto loop;
24554462Smckusick }
24654462Smckusick if (ap->a_waitfor == MNT_WAIT) {
24754462Smckusick while (vp->v_numoutput) {
24854462Smckusick vp->v_flag |= VBWAIT;
24954462Smckusick sleep((caddr_t)&vp->v_numoutput, PRIBIO + 1);
25054462Smckusick }
25154462Smckusick #ifdef DIAGNOSTIC
25265237Smckusick if (vp->v_dirtyblkhd.lh_first) {
25354462Smckusick vprint("ffs_fsync: dirty", vp);
25454462Smckusick goto loop;
25554462Smckusick }
25654462Smckusick #endif
25754462Smckusick }
25854462Smckusick splx(s);
25954763Smckusick tv = time;
26064438Sbostic return (VOP_UPDATE(ap->a_vp, &tv, &tv, ap->a_waitfor == MNT_WAIT));
26164438Sbostic }
26267409Smckusick
26367409Smckusick /*
26467409Smckusick * Reclaim an inode so that it can be used for other purposes.
26567409Smckusick */
26667409Smckusick int
ffs_reclaim(ap)26767409Smckusick ffs_reclaim(ap)
26867409Smckusick struct vop_reclaim_args /* {
26967409Smckusick struct vnode *a_vp;
270*69416Smckusick struct proc *a_p;
27167409Smckusick } */ *ap;
27267409Smckusick {
27367409Smckusick register struct vnode *vp = ap->a_vp;
27467409Smckusick int error;
27567409Smckusick
276*69416Smckusick if (error = ufs_reclaim(vp, ap->a_p))
27767409Smckusick return (error);
27868117Smckusick FREE(vp->v_data, VFSTOUFS(vp->v_mount)->um_devvp->v_tag == VT_MFS ?
27968117Smckusick M_MFSNODE : M_FFSNODE);
28067409Smckusick vp->v_data = NULL;
28167409Smckusick return (0);
28267409Smckusick }
283