xref: /csrg-svn/sys/ufs/lfs/lfs_vnops.c (revision 67575)
123405Smckusick /*
263375Sbostic  * Copyright (c) 1986, 1989, 1991, 1993
363375Sbostic  *	The Regents of the University of California.  All rights reserved.
423405Smckusick  *
544539Sbostic  * %sccs.include.redist.c%
637737Smckusick  *
7*67575Spendry  *	@(#)lfs_vnops.c	8.7 (Berkeley) 07/28/94
823405Smckusick  */
937Sbill 
1051482Sbostic #include <sys/param.h>
1151482Sbostic #include <sys/systm.h>
1251482Sbostic #include <sys/namei.h>
1351482Sbostic #include <sys/resourcevar.h>
1451482Sbostic #include <sys/kernel.h>
1551482Sbostic #include <sys/file.h>
1651482Sbostic #include <sys/stat.h>
1751482Sbostic #include <sys/buf.h>
1851482Sbostic #include <sys/proc.h>
1951482Sbostic #include <sys/conf.h>
2051482Sbostic #include <sys/mount.h>
2151482Sbostic #include <sys/vnode.h>
2251482Sbostic #include <sys/malloc.h>
2337Sbill 
2453321Smckusick #include <vm/vm.h>
2553321Smckusick 
2655460Sbostic #include <miscfs/specfs/specdev.h>
2755460Sbostic #include <miscfs/fifofs/fifo.h>
2855460Sbostic 
2951502Sbostic #include <ufs/ufs/quota.h>
3051502Sbostic #include <ufs/ufs/inode.h>
3151502Sbostic #include <ufs/ufs/dir.h>
3255936Sbostic #include <ufs/ufs/ufsmount.h>
3351502Sbostic #include <ufs/ufs/ufs_extern.h>
3447571Skarels 
3551502Sbostic #include <ufs/lfs/lfs.h>
3651502Sbostic #include <ufs/lfs/lfs_extern.h>
3751134Sbostic 
3851482Sbostic /* Global vfs data structures for lfs. */
3953533Sheideman int (**lfs_vnodeop_p)();
4053533Sheideman struct vnodeopv_entry_desc lfs_vnodeop_entries[] = {
4153533Sheideman 	{ &vop_default_desc, vn_default_error },
4253533Sheideman 	{ &vop_lookup_desc, ufs_lookup },		/* lookup */
4357067Smargo 	{ &vop_create_desc, ufs_create },		/* create */
44*67575Spendry 	{ &vop_whiteout_desc, ufs_whiteout },		/* whiteout */
4557067Smargo 	{ &vop_mknod_desc, ufs_mknod },			/* mknod */
4654030Smckusick 	{ &vop_open_desc, ufs_open },			/* open */
4756053Sbostic 	{ &vop_close_desc, lfs_close },			/* close */
4853533Sheideman 	{ &vop_access_desc, ufs_access },		/* access */
4955936Sbostic 	{ &vop_getattr_desc, lfs_getattr },		/* getattr */
5053533Sheideman 	{ &vop_setattr_desc, ufs_setattr },		/* setattr */
5154030Smckusick 	{ &vop_read_desc, lfs_read },			/* read */
5254030Smckusick 	{ &vop_write_desc, lfs_write },			/* write */
5354030Smckusick 	{ &vop_ioctl_desc, ufs_ioctl },			/* ioctl */
5453533Sheideman 	{ &vop_select_desc, ufs_select },		/* select */
5554030Smckusick 	{ &vop_mmap_desc, ufs_mmap },			/* mmap */
5654030Smckusick 	{ &vop_fsync_desc, lfs_fsync },			/* fsync */
5754030Smckusick 	{ &vop_seek_desc, ufs_seek },			/* seek */
5857067Smargo 	{ &vop_remove_desc, ufs_remove },		/* remove */
5957067Smargo 	{ &vop_link_desc, ufs_link },			/* link */
6057067Smargo 	{ &vop_rename_desc, ufs_rename },		/* rename */
6157067Smargo 	{ &vop_mkdir_desc, ufs_mkdir },			/* mkdir */
6257067Smargo 	{ &vop_rmdir_desc, ufs_rmdir },			/* rmdir */
6357067Smargo 	{ &vop_symlink_desc, ufs_symlink },		/* symlink */
6453533Sheideman 	{ &vop_readdir_desc, ufs_readdir },		/* readdir */
6553533Sheideman 	{ &vop_readlink_desc, ufs_readlink },		/* readlink */
6653533Sheideman 	{ &vop_abortop_desc, ufs_abortop },		/* abortop */
6765239Smckusick 	{ &vop_inactive_desc, lfs_inactive },		/* inactive */
6867411Smckusick 	{ &vop_reclaim_desc, lfs_reclaim },		/* reclaim */
6954030Smckusick 	{ &vop_lock_desc, ufs_lock },			/* lock */
7053533Sheideman 	{ &vop_unlock_desc, ufs_unlock },		/* unlock */
7156474Smargo 	{ &vop_bmap_desc, ufs_bmap },			/* bmap */
7253533Sheideman 	{ &vop_strategy_desc, ufs_strategy },		/* strategy */
7354030Smckusick 	{ &vop_print_desc, ufs_print },			/* print */
7453533Sheideman 	{ &vop_islocked_desc, ufs_islocked },		/* islocked */
7560395Smckusick 	{ &vop_pathconf_desc, ufs_pathconf },		/* pathconf */
7653533Sheideman 	{ &vop_advlock_desc, ufs_advlock },		/* advlock */
7753533Sheideman 	{ &vop_blkatoff_desc, lfs_blkatoff },		/* blkatoff */
7853533Sheideman 	{ &vop_valloc_desc, lfs_valloc },		/* valloc */
7954030Smckusick 	{ &vop_vfree_desc, lfs_vfree },			/* vfree */
8053533Sheideman 	{ &vop_truncate_desc, lfs_truncate },		/* truncate */
8153533Sheideman 	{ &vop_update_desc, lfs_update },		/* update */
8253533Sheideman 	{ &vop_bwrite_desc, lfs_bwrite },		/* bwrite */
8353533Sheideman 	{ (struct vnodeop_desc*)NULL, (int(*)())NULL }
8451482Sbostic };
8553533Sheideman struct vnodeopv_desc lfs_vnodeop_opv_desc =
8653533Sheideman 	{ &lfs_vnodeop_p, lfs_vnodeop_entries };
876254Sroot 
8853533Sheideman int (**lfs_specop_p)();
8953533Sheideman struct vnodeopv_entry_desc lfs_specop_entries[] = {
9053533Sheideman 	{ &vop_default_desc, vn_default_error },
9153533Sheideman 	{ &vop_lookup_desc, spec_lookup },		/* lookup */
9253533Sheideman 	{ &vop_create_desc, spec_create },		/* create */
9353533Sheideman 	{ &vop_mknod_desc, spec_mknod },		/* mknod */
9454030Smckusick 	{ &vop_open_desc, spec_open },			/* open */
9553533Sheideman 	{ &vop_close_desc, ufsspec_close },		/* close */
9653533Sheideman 	{ &vop_access_desc, ufs_access },		/* access */
9755936Sbostic 	{ &vop_getattr_desc, lfs_getattr },		/* getattr */
9853533Sheideman 	{ &vop_setattr_desc, ufs_setattr },		/* setattr */
9953533Sheideman 	{ &vop_read_desc, ufsspec_read },		/* read */
10053533Sheideman 	{ &vop_write_desc, ufsspec_write },		/* write */
10153533Sheideman 	{ &vop_ioctl_desc, spec_ioctl },		/* ioctl */
10253533Sheideman 	{ &vop_select_desc, spec_select },		/* select */
10354030Smckusick 	{ &vop_mmap_desc, spec_mmap },			/* mmap */
10453533Sheideman 	{ &vop_fsync_desc, spec_fsync },		/* fsync */
10554030Smckusick 	{ &vop_seek_desc, spec_seek },			/* seek */
10653533Sheideman 	{ &vop_remove_desc, spec_remove },		/* remove */
10754030Smckusick 	{ &vop_link_desc, spec_link },			/* link */
10853533Sheideman 	{ &vop_rename_desc, spec_rename },		/* rename */
10953533Sheideman 	{ &vop_mkdir_desc, spec_mkdir },		/* mkdir */
11053533Sheideman 	{ &vop_rmdir_desc, spec_rmdir },		/* rmdir */
11153533Sheideman 	{ &vop_symlink_desc, spec_symlink },		/* symlink */
11253533Sheideman 	{ &vop_readdir_desc, spec_readdir },		/* readdir */
11353533Sheideman 	{ &vop_readlink_desc, spec_readlink },		/* readlink */
11453533Sheideman 	{ &vop_abortop_desc, spec_abortop },		/* abortop */
11565239Smckusick 	{ &vop_inactive_desc, lfs_inactive },		/* inactive */
11667411Smckusick 	{ &vop_reclaim_desc, lfs_reclaim },		/* reclaim */
11754030Smckusick 	{ &vop_lock_desc, ufs_lock },			/* lock */
11853533Sheideman 	{ &vop_unlock_desc, ufs_unlock },		/* unlock */
11954030Smckusick 	{ &vop_bmap_desc, spec_bmap },			/* bmap */
12053533Sheideman 	{ &vop_strategy_desc, spec_strategy },		/* strategy */
12154030Smckusick 	{ &vop_print_desc, ufs_print },			/* print */
12253533Sheideman 	{ &vop_islocked_desc, ufs_islocked },		/* islocked */
12360395Smckusick 	{ &vop_pathconf_desc, spec_pathconf },		/* pathconf */
12453533Sheideman 	{ &vop_advlock_desc, spec_advlock },		/* advlock */
12553533Sheideman 	{ &vop_blkatoff_desc, spec_blkatoff },		/* blkatoff */
12653533Sheideman 	{ &vop_valloc_desc, spec_valloc },		/* valloc */
12754030Smckusick 	{ &vop_vfree_desc, lfs_vfree },			/* vfree */
12853533Sheideman 	{ &vop_truncate_desc, spec_truncate },		/* truncate */
12953533Sheideman 	{ &vop_update_desc, lfs_update },		/* update */
13053533Sheideman 	{ &vop_bwrite_desc, lfs_bwrite },		/* bwrite */
13153533Sheideman 	{ (struct vnodeop_desc*)NULL, (int(*)())NULL }
13251558Smckusick };
13353533Sheideman struct vnodeopv_desc lfs_specop_opv_desc =
13453533Sheideman 	{ &lfs_specop_p, lfs_specop_entries };
13551558Smckusick 
13651558Smckusick #ifdef FIFO
13753533Sheideman int (**lfs_fifoop_p)();
13853533Sheideman struct vnodeopv_entry_desc lfs_fifoop_entries[] = {
13953533Sheideman 	{ &vop_default_desc, vn_default_error },
14053533Sheideman 	{ &vop_lookup_desc, fifo_lookup },		/* lookup */
14153533Sheideman 	{ &vop_create_desc, fifo_create },		/* create */
14253533Sheideman 	{ &vop_mknod_desc, fifo_mknod },		/* mknod */
14354030Smckusick 	{ &vop_open_desc, fifo_open },			/* open */
14453533Sheideman 	{ &vop_close_desc, ufsfifo_close },		/* close */
14553533Sheideman 	{ &vop_access_desc, ufs_access },		/* access */
14655936Sbostic 	{ &vop_getattr_desc, lfs_getattr },		/* getattr */
14753533Sheideman 	{ &vop_setattr_desc, ufs_setattr },		/* setattr */
14853533Sheideman 	{ &vop_read_desc, ufsfifo_read },		/* read */
14953533Sheideman 	{ &vop_write_desc, ufsfifo_write },		/* write */
15053533Sheideman 	{ &vop_ioctl_desc, fifo_ioctl },		/* ioctl */
15153533Sheideman 	{ &vop_select_desc, fifo_select },		/* select */
15254030Smckusick 	{ &vop_mmap_desc, fifo_mmap },			/* mmap */
15353533Sheideman 	{ &vop_fsync_desc, fifo_fsync },		/* fsync */
15454030Smckusick 	{ &vop_seek_desc, fifo_seek },			/* seek */
15553533Sheideman 	{ &vop_remove_desc, fifo_remove },		/* remove */
15654030Smckusick 	{ &vop_link_desc, fifo_link },			/* link */
15753533Sheideman 	{ &vop_rename_desc, fifo_rename },		/* rename */
15853533Sheideman 	{ &vop_mkdir_desc, fifo_mkdir },		/* mkdir */
15953533Sheideman 	{ &vop_rmdir_desc, fifo_rmdir },		/* rmdir */
16053533Sheideman 	{ &vop_symlink_desc, fifo_symlink },		/* symlink */
16153533Sheideman 	{ &vop_readdir_desc, fifo_readdir },		/* readdir */
16253533Sheideman 	{ &vop_readlink_desc, fifo_readlink },		/* readlink */
16353533Sheideman 	{ &vop_abortop_desc, fifo_abortop },		/* abortop */
16465239Smckusick 	{ &vop_inactive_desc, lfs_inactive },		/* inactive */
16567411Smckusick 	{ &vop_reclaim_desc, lfs_reclaim },		/* reclaim */
16654030Smckusick 	{ &vop_lock_desc, ufs_lock },			/* lock */
16753533Sheideman 	{ &vop_unlock_desc, ufs_unlock },		/* unlock */
16854030Smckusick 	{ &vop_bmap_desc, fifo_bmap },			/* bmap */
16953533Sheideman 	{ &vop_strategy_desc, fifo_strategy },		/* strategy */
17054030Smckusick 	{ &vop_print_desc, ufs_print },			/* print */
17153533Sheideman 	{ &vop_islocked_desc, ufs_islocked },		/* islocked */
17260395Smckusick 	{ &vop_pathconf_desc, fifo_pathconf },		/* pathconf */
17353533Sheideman 	{ &vop_advlock_desc, fifo_advlock },		/* advlock */
17453533Sheideman 	{ &vop_blkatoff_desc, fifo_blkatoff },		/* blkatoff */
17553533Sheideman 	{ &vop_valloc_desc, fifo_valloc },		/* valloc */
17654030Smckusick 	{ &vop_vfree_desc, lfs_vfree },			/* vfree */
17753533Sheideman 	{ &vop_truncate_desc, fifo_truncate },		/* truncate */
17853533Sheideman 	{ &vop_update_desc, lfs_update },		/* update */
17953533Sheideman 	{ &vop_bwrite_desc, lfs_bwrite },		/* bwrite */
18053533Sheideman 	{ (struct vnodeop_desc*)NULL, (int(*)())NULL }
18151558Smckusick };
18253533Sheideman struct vnodeopv_desc lfs_fifoop_opv_desc =
18353533Sheideman 	{ &lfs_fifoop_p, lfs_fifoop_entries };
18451558Smckusick #endif /* FIFO */
18551558Smckusick 
18664417Sbostic #define	LFS_READWRITE
18764417Sbostic #include <ufs/ufs/ufs_readwrite.c>
18864417Sbostic #undef	LFS_READWRITE
18939608Smckusick 
19039608Smckusick /*
19137737Smckusick  * Synch an open file.
1929167Ssam  */
19337737Smckusick /* ARGSUSED */
19454030Smckusick lfs_fsync(ap)
19554692Sbostic 	struct vop_fsync_args /* {
19654692Sbostic 		struct vnode *a_vp;
19754692Sbostic 		struct ucred *a_cred;
19854692Sbostic 		int a_waitfor;
19954692Sbostic 		struct proc *a_p;
20054692Sbostic 	} */ *ap;
2017701Ssam {
20254765Smckusick 	struct timeval tv;
2037701Ssam 
20454765Smckusick 	tv = time;
20555547Sbostic 	return (VOP_UPDATE(ap->a_vp, &tv, &tv,
20655547Sbostic 	    ap->a_waitfor == MNT_WAIT ? LFS_SYNC : 0));
20737737Smckusick }
20851558Smckusick 
20951558Smckusick /*
21054264Sbostic  * These macros are used to bracket UFS directory ops, so that we can
21154264Sbostic  * identify all the pages touched during directory ops which need to
21254264Sbostic  * be ordered and flushed atomically, so that they may be recovered.
21354264Sbostic  */
21454264Sbostic #define	SET_DIROP(fs) {							\
21554264Sbostic 	if ((fs)->lfs_writer)						\
21655547Sbostic 		tsleep(&(fs)->lfs_dirops, PRIBIO + 1, "lfs_dirop", 0);	\
21754264Sbostic 	++(fs)->lfs_dirops;						\
21854264Sbostic 	(fs)->lfs_doifile = 1;						\
21954264Sbostic }
22054264Sbostic 
22154264Sbostic #define	SET_ENDOP(fs) {							\
22254264Sbostic 	--(fs)->lfs_dirops;						\
22354264Sbostic 	if (!(fs)->lfs_dirops)						\
22454264Sbostic 		wakeup(&(fs)->lfs_writer);				\
22554264Sbostic }
22654264Sbostic 
22754264Sbostic #define	MARK_VNODE(dvp)	(dvp)->v_flag |= VDIROP
22854264Sbostic 
22954264Sbostic int
23054264Sbostic lfs_symlink(ap)
23154692Sbostic 	struct vop_symlink_args /* {
23254692Sbostic 		struct vnode *a_dvp;
23354692Sbostic 		struct vnode **a_vpp;
23454692Sbostic 		struct componentname *a_cnp;
23554692Sbostic 		struct vattr *a_vap;
23654692Sbostic 		char *a_target;
23754692Sbostic 	} */ *ap;
23854264Sbostic {
23954264Sbostic 	int ret;
24054264Sbostic 
24154264Sbostic 	SET_DIROP(VTOI(ap->a_dvp)->i_lfs);
24254264Sbostic 	MARK_VNODE(ap->a_dvp);
24354264Sbostic 	ret = ufs_symlink(ap);
24454264Sbostic 	SET_ENDOP(VTOI(ap->a_dvp)->i_lfs);
24554264Sbostic 	return (ret);
24654264Sbostic }
24754264Sbostic 
24854264Sbostic int
24954264Sbostic lfs_mknod(ap)
25054692Sbostic 	struct vop_mknod_args /* {
25154692Sbostic 		struct vnode *a_dvp;
25254692Sbostic 		struct vnode **a_vpp;
25354692Sbostic 		struct componentname *a_cnp;
25454692Sbostic 		struct vattr *a_vap;
25554692Sbostic 	} */ *ap;
25654264Sbostic {
25754264Sbostic 	int ret;
25854264Sbostic 
25954264Sbostic 	SET_DIROP(VTOI(ap->a_dvp)->i_lfs);
26054264Sbostic 	MARK_VNODE(ap->a_dvp);
26154264Sbostic 	ret = ufs_mknod(ap);
26254264Sbostic 	SET_ENDOP(VTOI(ap->a_dvp)->i_lfs);
26354264Sbostic 	return (ret);
26454264Sbostic }
26554264Sbostic 
26654264Sbostic int
26754264Sbostic lfs_create(ap)
26854692Sbostic 	struct vop_create_args /* {
26954692Sbostic 		struct vnode *a_dvp;
27054692Sbostic 		struct vnode **a_vpp;
27154692Sbostic 		struct componentname *a_cnp;
27254692Sbostic 		struct vattr *a_vap;
27354692Sbostic 	} */ *ap;
27454264Sbostic {
27554264Sbostic 	int ret;
27654264Sbostic 
27754264Sbostic 	SET_DIROP(VTOI(ap->a_dvp)->i_lfs);
27854264Sbostic 	MARK_VNODE(ap->a_dvp);
27954264Sbostic 	ret = ufs_create(ap);
28054264Sbostic 	SET_ENDOP(VTOI(ap->a_dvp)->i_lfs);
28154264Sbostic 	return (ret);
28254264Sbostic }
28354264Sbostic 
28454264Sbostic int
28554264Sbostic lfs_mkdir(ap)
28654692Sbostic 	struct vop_mkdir_args /* {
28754692Sbostic 		struct vnode *a_dvp;
28854692Sbostic 		struct vnode **a_vpp;
28954692Sbostic 		struct componentname *a_cnp;
29054692Sbostic 		struct vattr *a_vap;
29154692Sbostic 	} */ *ap;
29254264Sbostic {
29354264Sbostic 	int ret;
29454264Sbostic 
29554264Sbostic 	SET_DIROP(VTOI(ap->a_dvp)->i_lfs);
29654264Sbostic 	MARK_VNODE(ap->a_dvp);
29754264Sbostic 	ret = ufs_mkdir(ap);
29854264Sbostic 	SET_ENDOP(VTOI(ap->a_dvp)->i_lfs);
29954264Sbostic 	return (ret);
30054264Sbostic }
30154264Sbostic 
30254264Sbostic int
30354264Sbostic lfs_remove(ap)
30454692Sbostic 	struct vop_remove_args /* {
30554692Sbostic 		struct vnode *a_dvp;
30654692Sbostic 		struct vnode *a_vp;
30754692Sbostic 		struct componentname *a_cnp;
30854692Sbostic 	} */ *ap;
30954264Sbostic {
31054264Sbostic 	int ret;
31154264Sbostic 
31254264Sbostic 	SET_DIROP(VTOI(ap->a_dvp)->i_lfs);
31354264Sbostic 	MARK_VNODE(ap->a_dvp);
31454264Sbostic 	MARK_VNODE(ap->a_vp);
31554264Sbostic 	ret = ufs_remove(ap);
31654264Sbostic 	SET_ENDOP(VTOI(ap->a_dvp)->i_lfs);
31754264Sbostic 	return (ret);
31854264Sbostic }
31954264Sbostic 
32054264Sbostic int
32154264Sbostic lfs_rmdir(ap)
32254692Sbostic 	struct vop_rmdir_args /* {
32354692Sbostic 		struct vnodeop_desc *a_desc;
32454692Sbostic 		struct vnode *a_dvp;
32554692Sbostic 		struct vnode *a_vp;
32654692Sbostic 		struct componentname *a_cnp;
32754692Sbostic 	} */ *ap;
32854264Sbostic {
32954264Sbostic 	int ret;
33054264Sbostic 
33154264Sbostic 	SET_DIROP(VTOI(ap->a_dvp)->i_lfs);
33254264Sbostic 	MARK_VNODE(ap->a_dvp);
33354264Sbostic 	MARK_VNODE(ap->a_vp);
33454264Sbostic 	ret = ufs_rmdir(ap);
33554264Sbostic 	SET_ENDOP(VTOI(ap->a_dvp)->i_lfs);
33654264Sbostic 	return (ret);
33754264Sbostic }
33854264Sbostic 
33954264Sbostic int
34054264Sbostic lfs_link(ap)
34154692Sbostic 	struct vop_link_args /* {
34254692Sbostic 		struct vnode *a_vp;
34354692Sbostic 		struct vnode *a_tdvp;
34454692Sbostic 		struct componentname *a_cnp;
34554692Sbostic 	} */ *ap;
34654264Sbostic {
34754264Sbostic 	int ret;
34854264Sbostic 
34954264Sbostic 	SET_DIROP(VTOI(ap->a_vp)->i_lfs);
35054264Sbostic 	MARK_VNODE(ap->a_vp);
35154264Sbostic 	ret = ufs_link(ap);
35254264Sbostic 	SET_ENDOP(VTOI(ap->a_vp)->i_lfs);
35354264Sbostic 	return (ret);
35454264Sbostic }
35554264Sbostic 
35654264Sbostic int
35754264Sbostic lfs_rename(ap)
35854692Sbostic 	struct vop_rename_args  /* {
35954692Sbostic 		struct vnode *a_fdvp;
36054692Sbostic 		struct vnode *a_fvp;
36154692Sbostic 		struct componentname *a_fcnp;
36254692Sbostic 		struct vnode *a_tdvp;
36354692Sbostic 		struct vnode *a_tvp;
36454692Sbostic 		struct componentname *a_tcnp;
36554692Sbostic 	} */ *ap;
36654264Sbostic {
36754264Sbostic 	int ret;
36854264Sbostic 
36954264Sbostic 	SET_DIROP(VTOI(ap->a_fdvp)->i_lfs);
37054264Sbostic 	MARK_VNODE(ap->a_fdvp);
37154264Sbostic 	MARK_VNODE(ap->a_tdvp);
37254264Sbostic 	ret = ufs_rename(ap);
37354264Sbostic 	SET_ENDOP(VTOI(ap->a_fdvp)->i_lfs);
37454264Sbostic 	return (ret);
37554264Sbostic }
37655936Sbostic /* XXX hack to avoid calling ITIMES in getattr */
37755936Sbostic int
37855936Sbostic lfs_getattr(ap)
37955936Sbostic 	struct vop_getattr_args /* {
38055936Sbostic 		struct vnode *a_vp;
38155936Sbostic 		struct vattr *a_vap;
38255936Sbostic 		struct ucred *a_cred;
38355936Sbostic 		struct proc *a_p;
38455936Sbostic 	} */ *ap;
38555936Sbostic {
38655936Sbostic 	register struct vnode *vp = ap->a_vp;
38755936Sbostic 	register struct inode *ip = VTOI(vp);
38855936Sbostic 	register struct vattr *vap = ap->a_vap;
38955936Sbostic 	/*
39055936Sbostic 	 * Copy from inode table
39155936Sbostic 	 */
39255936Sbostic 	vap->va_fsid = ip->i_dev;
39355936Sbostic 	vap->va_fileid = ip->i_number;
39455936Sbostic 	vap->va_mode = ip->i_mode & ~IFMT;
39555936Sbostic 	vap->va_nlink = ip->i_nlink;
39655936Sbostic 	vap->va_uid = ip->i_uid;
39755936Sbostic 	vap->va_gid = ip->i_gid;
39855936Sbostic 	vap->va_rdev = (dev_t)ip->i_rdev;
39955936Sbostic 	vap->va_size = ip->i_din.di_size;
40055936Sbostic 	vap->va_atime = ip->i_atime;
40155936Sbostic 	vap->va_mtime = ip->i_mtime;
40255936Sbostic 	vap->va_ctime = ip->i_ctime;
40355936Sbostic 	vap->va_flags = ip->i_flags;
40455936Sbostic 	vap->va_gen = ip->i_gen;
40555936Sbostic 	/* this doesn't belong here */
40655936Sbostic 	if (vp->v_type == VBLK)
40755936Sbostic 		vap->va_blocksize = BLKDEV_IOSIZE;
40855936Sbostic 	else if (vp->v_type == VCHR)
40955936Sbostic 		vap->va_blocksize = MAXBSIZE;
41055936Sbostic 	else
41155936Sbostic 		vap->va_blocksize = vp->v_mount->mnt_stat.f_iosize;
41255936Sbostic 	vap->va_bytes = dbtob(ip->i_blocks);
41355936Sbostic 	vap->va_type = vp->v_type;
41455936Sbostic 	vap->va_filerev = ip->i_modrev;
41555936Sbostic 	return (0);
41655936Sbostic }
41756053Sbostic /*
41856053Sbostic  * Close called
41956053Sbostic  *
42056053Sbostic  * XXX -- we were using ufs_close, but since it updates the
42156053Sbostic  * times on the inode, we might need to bump the uinodes
42256053Sbostic  * count.
42356053Sbostic  */
42456053Sbostic /* ARGSUSED */
42556053Sbostic int
42656053Sbostic lfs_close(ap)
42756053Sbostic 	struct vop_close_args /* {
42856053Sbostic 		struct vnode *a_vp;
42956053Sbostic 		int  a_fflag;
43056053Sbostic 		struct ucred *a_cred;
43156053Sbostic 		struct proc *a_p;
43256053Sbostic 	} */ *ap;
43356053Sbostic {
43456053Sbostic 	register struct vnode *vp = ap->a_vp;
43556053Sbostic 	register struct inode *ip = VTOI(vp);
43656053Sbostic 	int mod;
43756053Sbostic 
43864608Sbostic 	if (vp->v_usecount > 1 && !(ip->i_flag & IN_LOCKED)) {
43964608Sbostic 		mod = ip->i_flag & IN_MODIFIED;
44056053Sbostic 		ITIMES(ip, &time, &time);
44164608Sbostic 		if (!mod && ip->i_flag & IN_MODIFIED)
44256053Sbostic 			ip->i_lfs->lfs_uinodes++;
44356053Sbostic 	}
44456053Sbostic 	return (0);
44556053Sbostic }
44656053Sbostic 
44765239Smckusick /*
44865239Smckusick  * Stub inactive routine that avoid calling ufs_inactive in some cases.
44965239Smckusick  */
45065239Smckusick int lfs_no_inactive = 0;
45165239Smckusick 
45265239Smckusick int
45365239Smckusick lfs_inactive(ap)
45465239Smckusick 	struct vop_inactive_args /* {
45565239Smckusick 		struct vnode *a_vp;
45665239Smckusick 	} */ *ap;
45765239Smckusick {
45865239Smckusick 
45965239Smckusick 	if (lfs_no_inactive)
46065239Smckusick 		return (0);
46165239Smckusick 	return (ufs_inactive(ap));
46265239Smckusick }
46367411Smckusick 
46467411Smckusick /*
46567411Smckusick  * Reclaim an inode so that it can be used for other purposes.
46667411Smckusick  */
46767411Smckusick int
46867411Smckusick lfs_reclaim(ap)
46967411Smckusick 	struct vop_reclaim_args /* {
47067411Smckusick 		struct vnode *a_vp;
47167411Smckusick 	} */ *ap;
47267411Smckusick {
47367411Smckusick 	register struct vnode *vp = ap->a_vp;
47467411Smckusick 	int error;
47567411Smckusick 
47667411Smckusick 	if (error = ufs_reclaim(vp))
47767411Smckusick 		return (error);
47867411Smckusick 	FREE(vp->v_data, M_LFSNODE);
47967411Smckusick 	vp->v_data = NULL;
48067411Smckusick 	return (0);
48167411Smckusick }
482