xref: /csrg-svn/sys/ufs/lfs/lfs_vnops.c (revision 64608)
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*64608Sbostic  *	@(#)lfs_vnops.c	8.4 (Berkeley) 09/23/93
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 */
4457067Smargo 	{ &vop_mknod_desc, ufs_mknod },			/* mknod */
4554030Smckusick 	{ &vop_open_desc, ufs_open },			/* open */
4656053Sbostic 	{ &vop_close_desc, lfs_close },			/* close */
4753533Sheideman 	{ &vop_access_desc, ufs_access },		/* access */
4855936Sbostic 	{ &vop_getattr_desc, lfs_getattr },		/* getattr */
4953533Sheideman 	{ &vop_setattr_desc, ufs_setattr },		/* setattr */
5054030Smckusick 	{ &vop_read_desc, lfs_read },			/* read */
5154030Smckusick 	{ &vop_write_desc, lfs_write },			/* write */
5254030Smckusick 	{ &vop_ioctl_desc, ufs_ioctl },			/* ioctl */
5353533Sheideman 	{ &vop_select_desc, ufs_select },		/* select */
5454030Smckusick 	{ &vop_mmap_desc, ufs_mmap },			/* mmap */
5554030Smckusick 	{ &vop_fsync_desc, lfs_fsync },			/* fsync */
5654030Smckusick 	{ &vop_seek_desc, ufs_seek },			/* seek */
5757067Smargo 	{ &vop_remove_desc, ufs_remove },		/* remove */
5857067Smargo 	{ &vop_link_desc, ufs_link },			/* link */
5957067Smargo 	{ &vop_rename_desc, ufs_rename },		/* rename */
6057067Smargo 	{ &vop_mkdir_desc, ufs_mkdir },			/* mkdir */
6157067Smargo 	{ &vop_rmdir_desc, ufs_rmdir },			/* rmdir */
6257067Smargo 	{ &vop_symlink_desc, ufs_symlink },		/* symlink */
6353533Sheideman 	{ &vop_readdir_desc, ufs_readdir },		/* readdir */
6453533Sheideman 	{ &vop_readlink_desc, ufs_readlink },		/* readlink */
6553533Sheideman 	{ &vop_abortop_desc, ufs_abortop },		/* abortop */
6657067Smargo 	{ &vop_inactive_desc, ufs_inactive },		/* inactive */
6753533Sheideman 	{ &vop_reclaim_desc, ufs_reclaim },		/* reclaim */
6854030Smckusick 	{ &vop_lock_desc, ufs_lock },			/* lock */
6953533Sheideman 	{ &vop_unlock_desc, ufs_unlock },		/* unlock */
7056474Smargo 	{ &vop_bmap_desc, ufs_bmap },			/* bmap */
7153533Sheideman 	{ &vop_strategy_desc, ufs_strategy },		/* strategy */
7254030Smckusick 	{ &vop_print_desc, ufs_print },			/* print */
7353533Sheideman 	{ &vop_islocked_desc, ufs_islocked },		/* islocked */
7460395Smckusick 	{ &vop_pathconf_desc, ufs_pathconf },		/* pathconf */
7553533Sheideman 	{ &vop_advlock_desc, ufs_advlock },		/* advlock */
7653533Sheideman 	{ &vop_blkatoff_desc, lfs_blkatoff },		/* blkatoff */
7753533Sheideman 	{ &vop_valloc_desc, lfs_valloc },		/* valloc */
7854030Smckusick 	{ &vop_vfree_desc, lfs_vfree },			/* vfree */
7953533Sheideman 	{ &vop_truncate_desc, lfs_truncate },		/* truncate */
8053533Sheideman 	{ &vop_update_desc, lfs_update },		/* update */
8153533Sheideman 	{ &vop_bwrite_desc, lfs_bwrite },		/* bwrite */
8253533Sheideman 	{ (struct vnodeop_desc*)NULL, (int(*)())NULL }
8351482Sbostic };
8453533Sheideman struct vnodeopv_desc lfs_vnodeop_opv_desc =
8553533Sheideman 	{ &lfs_vnodeop_p, lfs_vnodeop_entries };
866254Sroot 
8753533Sheideman int (**lfs_specop_p)();
8853533Sheideman struct vnodeopv_entry_desc lfs_specop_entries[] = {
8953533Sheideman 	{ &vop_default_desc, vn_default_error },
9053533Sheideman 	{ &vop_lookup_desc, spec_lookup },		/* lookup */
9153533Sheideman 	{ &vop_create_desc, spec_create },		/* create */
9253533Sheideman 	{ &vop_mknod_desc, spec_mknod },		/* mknod */
9354030Smckusick 	{ &vop_open_desc, spec_open },			/* open */
9453533Sheideman 	{ &vop_close_desc, ufsspec_close },		/* close */
9553533Sheideman 	{ &vop_access_desc, ufs_access },		/* access */
9655936Sbostic 	{ &vop_getattr_desc, lfs_getattr },		/* getattr */
9753533Sheideman 	{ &vop_setattr_desc, ufs_setattr },		/* setattr */
9853533Sheideman 	{ &vop_read_desc, ufsspec_read },		/* read */
9953533Sheideman 	{ &vop_write_desc, ufsspec_write },		/* write */
10053533Sheideman 	{ &vop_ioctl_desc, spec_ioctl },		/* ioctl */
10153533Sheideman 	{ &vop_select_desc, spec_select },		/* select */
10254030Smckusick 	{ &vop_mmap_desc, spec_mmap },			/* mmap */
10353533Sheideman 	{ &vop_fsync_desc, spec_fsync },		/* fsync */
10454030Smckusick 	{ &vop_seek_desc, spec_seek },			/* seek */
10553533Sheideman 	{ &vop_remove_desc, spec_remove },		/* remove */
10654030Smckusick 	{ &vop_link_desc, spec_link },			/* link */
10753533Sheideman 	{ &vop_rename_desc, spec_rename },		/* rename */
10853533Sheideman 	{ &vop_mkdir_desc, spec_mkdir },		/* mkdir */
10953533Sheideman 	{ &vop_rmdir_desc, spec_rmdir },		/* rmdir */
11053533Sheideman 	{ &vop_symlink_desc, spec_symlink },		/* symlink */
11153533Sheideman 	{ &vop_readdir_desc, spec_readdir },		/* readdir */
11253533Sheideman 	{ &vop_readlink_desc, spec_readlink },		/* readlink */
11353533Sheideman 	{ &vop_abortop_desc, spec_abortop },		/* abortop */
11457067Smargo 	{ &vop_inactive_desc, ufs_inactive },		/* inactive */
11553533Sheideman 	{ &vop_reclaim_desc, ufs_reclaim },		/* reclaim */
11654030Smckusick 	{ &vop_lock_desc, ufs_lock },			/* lock */
11753533Sheideman 	{ &vop_unlock_desc, ufs_unlock },		/* unlock */
11854030Smckusick 	{ &vop_bmap_desc, spec_bmap },			/* bmap */
11953533Sheideman 	{ &vop_strategy_desc, spec_strategy },		/* strategy */
12054030Smckusick 	{ &vop_print_desc, ufs_print },			/* print */
12153533Sheideman 	{ &vop_islocked_desc, ufs_islocked },		/* islocked */
12260395Smckusick 	{ &vop_pathconf_desc, spec_pathconf },		/* pathconf */
12353533Sheideman 	{ &vop_advlock_desc, spec_advlock },		/* advlock */
12453533Sheideman 	{ &vop_blkatoff_desc, spec_blkatoff },		/* blkatoff */
12553533Sheideman 	{ &vop_valloc_desc, spec_valloc },		/* valloc */
12654030Smckusick 	{ &vop_vfree_desc, lfs_vfree },			/* vfree */
12753533Sheideman 	{ &vop_truncate_desc, spec_truncate },		/* truncate */
12853533Sheideman 	{ &vop_update_desc, lfs_update },		/* update */
12953533Sheideman 	{ &vop_bwrite_desc, lfs_bwrite },		/* bwrite */
13053533Sheideman 	{ (struct vnodeop_desc*)NULL, (int(*)())NULL }
13151558Smckusick };
13253533Sheideman struct vnodeopv_desc lfs_specop_opv_desc =
13353533Sheideman 	{ &lfs_specop_p, lfs_specop_entries };
13451558Smckusick 
13551558Smckusick #ifdef FIFO
13653533Sheideman int (**lfs_fifoop_p)();
13753533Sheideman struct vnodeopv_entry_desc lfs_fifoop_entries[] = {
13853533Sheideman 	{ &vop_default_desc, vn_default_error },
13953533Sheideman 	{ &vop_lookup_desc, fifo_lookup },		/* lookup */
14053533Sheideman 	{ &vop_create_desc, fifo_create },		/* create */
14153533Sheideman 	{ &vop_mknod_desc, fifo_mknod },		/* mknod */
14254030Smckusick 	{ &vop_open_desc, fifo_open },			/* open */
14353533Sheideman 	{ &vop_close_desc, ufsfifo_close },		/* close */
14453533Sheideman 	{ &vop_access_desc, ufs_access },		/* access */
14555936Sbostic 	{ &vop_getattr_desc, lfs_getattr },		/* getattr */
14653533Sheideman 	{ &vop_setattr_desc, ufs_setattr },		/* setattr */
14753533Sheideman 	{ &vop_read_desc, ufsfifo_read },		/* read */
14853533Sheideman 	{ &vop_write_desc, ufsfifo_write },		/* write */
14953533Sheideman 	{ &vop_ioctl_desc, fifo_ioctl },		/* ioctl */
15053533Sheideman 	{ &vop_select_desc, fifo_select },		/* select */
15154030Smckusick 	{ &vop_mmap_desc, fifo_mmap },			/* mmap */
15253533Sheideman 	{ &vop_fsync_desc, fifo_fsync },		/* fsync */
15354030Smckusick 	{ &vop_seek_desc, fifo_seek },			/* seek */
15453533Sheideman 	{ &vop_remove_desc, fifo_remove },		/* remove */
15554030Smckusick 	{ &vop_link_desc, fifo_link },			/* link */
15653533Sheideman 	{ &vop_rename_desc, fifo_rename },		/* rename */
15753533Sheideman 	{ &vop_mkdir_desc, fifo_mkdir },		/* mkdir */
15853533Sheideman 	{ &vop_rmdir_desc, fifo_rmdir },		/* rmdir */
15953533Sheideman 	{ &vop_symlink_desc, fifo_symlink },		/* symlink */
16053533Sheideman 	{ &vop_readdir_desc, fifo_readdir },		/* readdir */
16153533Sheideman 	{ &vop_readlink_desc, fifo_readlink },		/* readlink */
16253533Sheideman 	{ &vop_abortop_desc, fifo_abortop },		/* abortop */
16357067Smargo 	{ &vop_inactive_desc, ufs_inactive },		/* inactive */
16453533Sheideman 	{ &vop_reclaim_desc, ufs_reclaim },		/* reclaim */
16554030Smckusick 	{ &vop_lock_desc, ufs_lock },			/* lock */
16653533Sheideman 	{ &vop_unlock_desc, ufs_unlock },		/* unlock */
16754030Smckusick 	{ &vop_bmap_desc, fifo_bmap },			/* bmap */
16853533Sheideman 	{ &vop_strategy_desc, fifo_strategy },		/* strategy */
16954030Smckusick 	{ &vop_print_desc, ufs_print },			/* print */
17053533Sheideman 	{ &vop_islocked_desc, ufs_islocked },		/* islocked */
17160395Smckusick 	{ &vop_pathconf_desc, fifo_pathconf },		/* pathconf */
17253533Sheideman 	{ &vop_advlock_desc, fifo_advlock },		/* advlock */
17353533Sheideman 	{ &vop_blkatoff_desc, fifo_blkatoff },		/* blkatoff */
17453533Sheideman 	{ &vop_valloc_desc, fifo_valloc },		/* valloc */
17554030Smckusick 	{ &vop_vfree_desc, lfs_vfree },			/* vfree */
17653533Sheideman 	{ &vop_truncate_desc, fifo_truncate },		/* truncate */
17753533Sheideman 	{ &vop_update_desc, lfs_update },		/* update */
17853533Sheideman 	{ &vop_bwrite_desc, lfs_bwrite },		/* bwrite */
17953533Sheideman 	{ (struct vnodeop_desc*)NULL, (int(*)())NULL }
18051558Smckusick };
18153533Sheideman struct vnodeopv_desc lfs_fifoop_opv_desc =
18253533Sheideman 	{ &lfs_fifoop_p, lfs_fifoop_entries };
18351558Smckusick #endif /* FIFO */
18451558Smckusick 
18564417Sbostic #define	LFS_READWRITE
18664417Sbostic #include <ufs/ufs/ufs_readwrite.c>
18764417Sbostic #undef	LFS_READWRITE
18839608Smckusick 
18939608Smckusick /*
19037737Smckusick  * Synch an open file.
1919167Ssam  */
19237737Smckusick /* ARGSUSED */
19354030Smckusick lfs_fsync(ap)
19454692Sbostic 	struct vop_fsync_args /* {
19554692Sbostic 		struct vnode *a_vp;
19654692Sbostic 		struct ucred *a_cred;
19754692Sbostic 		int a_waitfor;
19854692Sbostic 		struct proc *a_p;
19954692Sbostic 	} */ *ap;
2007701Ssam {
20154765Smckusick 	struct timeval tv;
2027701Ssam 
20354765Smckusick 	tv = time;
20455547Sbostic 	return (VOP_UPDATE(ap->a_vp, &tv, &tv,
20555547Sbostic 	    ap->a_waitfor == MNT_WAIT ? LFS_SYNC : 0));
20637737Smckusick }
20751558Smckusick 
20851558Smckusick /*
20954264Sbostic  * These macros are used to bracket UFS directory ops, so that we can
21054264Sbostic  * identify all the pages touched during directory ops which need to
21154264Sbostic  * be ordered and flushed atomically, so that they may be recovered.
21254264Sbostic  */
21354264Sbostic #define	SET_DIROP(fs) {							\
21454264Sbostic 	if ((fs)->lfs_writer)						\
21555547Sbostic 		tsleep(&(fs)->lfs_dirops, PRIBIO + 1, "lfs_dirop", 0);	\
21654264Sbostic 	++(fs)->lfs_dirops;						\
21754264Sbostic 	(fs)->lfs_doifile = 1;						\
21854264Sbostic }
21954264Sbostic 
22054264Sbostic #define	SET_ENDOP(fs) {							\
22154264Sbostic 	--(fs)->lfs_dirops;						\
22254264Sbostic 	if (!(fs)->lfs_dirops)						\
22354264Sbostic 		wakeup(&(fs)->lfs_writer);				\
22454264Sbostic }
22554264Sbostic 
22654264Sbostic #define	MARK_VNODE(dvp)	(dvp)->v_flag |= VDIROP
22754264Sbostic 
22854264Sbostic int
22954264Sbostic lfs_symlink(ap)
23054692Sbostic 	struct vop_symlink_args /* {
23154692Sbostic 		struct vnode *a_dvp;
23254692Sbostic 		struct vnode **a_vpp;
23354692Sbostic 		struct componentname *a_cnp;
23454692Sbostic 		struct vattr *a_vap;
23554692Sbostic 		char *a_target;
23654692Sbostic 	} */ *ap;
23754264Sbostic {
23854264Sbostic 	int ret;
23954264Sbostic 
24054264Sbostic 	SET_DIROP(VTOI(ap->a_dvp)->i_lfs);
24154264Sbostic 	MARK_VNODE(ap->a_dvp);
24254264Sbostic 	ret = ufs_symlink(ap);
24354264Sbostic 	SET_ENDOP(VTOI(ap->a_dvp)->i_lfs);
24454264Sbostic 	return (ret);
24554264Sbostic }
24654264Sbostic 
24754264Sbostic int
24854264Sbostic lfs_mknod(ap)
24954692Sbostic 	struct vop_mknod_args /* {
25054692Sbostic 		struct vnode *a_dvp;
25154692Sbostic 		struct vnode **a_vpp;
25254692Sbostic 		struct componentname *a_cnp;
25354692Sbostic 		struct vattr *a_vap;
25454692Sbostic 	} */ *ap;
25554264Sbostic {
25654264Sbostic 	int ret;
25754264Sbostic 
25854264Sbostic 	SET_DIROP(VTOI(ap->a_dvp)->i_lfs);
25954264Sbostic 	MARK_VNODE(ap->a_dvp);
26054264Sbostic 	ret = ufs_mknod(ap);
26154264Sbostic 	SET_ENDOP(VTOI(ap->a_dvp)->i_lfs);
26254264Sbostic 	return (ret);
26354264Sbostic }
26454264Sbostic 
26554264Sbostic int
26654264Sbostic lfs_create(ap)
26754692Sbostic 	struct vop_create_args /* {
26854692Sbostic 		struct vnode *a_dvp;
26954692Sbostic 		struct vnode **a_vpp;
27054692Sbostic 		struct componentname *a_cnp;
27154692Sbostic 		struct vattr *a_vap;
27254692Sbostic 	} */ *ap;
27354264Sbostic {
27454264Sbostic 	int ret;
27554264Sbostic 
27654264Sbostic 	SET_DIROP(VTOI(ap->a_dvp)->i_lfs);
27754264Sbostic 	MARK_VNODE(ap->a_dvp);
27854264Sbostic 	ret = ufs_create(ap);
27954264Sbostic 	SET_ENDOP(VTOI(ap->a_dvp)->i_lfs);
28054264Sbostic 	return (ret);
28154264Sbostic }
28254264Sbostic 
28354264Sbostic int
28454264Sbostic lfs_mkdir(ap)
28554692Sbostic 	struct vop_mkdir_args /* {
28654692Sbostic 		struct vnode *a_dvp;
28754692Sbostic 		struct vnode **a_vpp;
28854692Sbostic 		struct componentname *a_cnp;
28954692Sbostic 		struct vattr *a_vap;
29054692Sbostic 	} */ *ap;
29154264Sbostic {
29254264Sbostic 	int ret;
29354264Sbostic 
29454264Sbostic 	SET_DIROP(VTOI(ap->a_dvp)->i_lfs);
29554264Sbostic 	MARK_VNODE(ap->a_dvp);
29654264Sbostic 	ret = ufs_mkdir(ap);
29754264Sbostic 	SET_ENDOP(VTOI(ap->a_dvp)->i_lfs);
29854264Sbostic 	return (ret);
29954264Sbostic }
30054264Sbostic 
30154264Sbostic int
30254264Sbostic lfs_remove(ap)
30354692Sbostic 	struct vop_remove_args /* {
30454692Sbostic 		struct vnode *a_dvp;
30554692Sbostic 		struct vnode *a_vp;
30654692Sbostic 		struct componentname *a_cnp;
30754692Sbostic 	} */ *ap;
30854264Sbostic {
30954264Sbostic 	int ret;
31054264Sbostic 
31154264Sbostic 	SET_DIROP(VTOI(ap->a_dvp)->i_lfs);
31254264Sbostic 	MARK_VNODE(ap->a_dvp);
31354264Sbostic 	MARK_VNODE(ap->a_vp);
31454264Sbostic 	ret = ufs_remove(ap);
31554264Sbostic 	SET_ENDOP(VTOI(ap->a_dvp)->i_lfs);
31654264Sbostic 	return (ret);
31754264Sbostic }
31854264Sbostic 
31954264Sbostic int
32054264Sbostic lfs_rmdir(ap)
32154692Sbostic 	struct vop_rmdir_args /* {
32254692Sbostic 		struct vnodeop_desc *a_desc;
32354692Sbostic 		struct vnode *a_dvp;
32454692Sbostic 		struct vnode *a_vp;
32554692Sbostic 		struct componentname *a_cnp;
32654692Sbostic 	} */ *ap;
32754264Sbostic {
32854264Sbostic 	int ret;
32954264Sbostic 
33054264Sbostic 	SET_DIROP(VTOI(ap->a_dvp)->i_lfs);
33154264Sbostic 	MARK_VNODE(ap->a_dvp);
33254264Sbostic 	MARK_VNODE(ap->a_vp);
33354264Sbostic 	ret = ufs_rmdir(ap);
33454264Sbostic 	SET_ENDOP(VTOI(ap->a_dvp)->i_lfs);
33554264Sbostic 	return (ret);
33654264Sbostic }
33754264Sbostic 
33854264Sbostic int
33954264Sbostic lfs_link(ap)
34054692Sbostic 	struct vop_link_args /* {
34154692Sbostic 		struct vnode *a_vp;
34254692Sbostic 		struct vnode *a_tdvp;
34354692Sbostic 		struct componentname *a_cnp;
34454692Sbostic 	} */ *ap;
34554264Sbostic {
34654264Sbostic 	int ret;
34754264Sbostic 
34854264Sbostic 	SET_DIROP(VTOI(ap->a_vp)->i_lfs);
34954264Sbostic 	MARK_VNODE(ap->a_vp);
35054264Sbostic 	ret = ufs_link(ap);
35154264Sbostic 	SET_ENDOP(VTOI(ap->a_vp)->i_lfs);
35254264Sbostic 	return (ret);
35354264Sbostic }
35454264Sbostic 
35554264Sbostic int
35654264Sbostic lfs_rename(ap)
35754692Sbostic 	struct vop_rename_args  /* {
35854692Sbostic 		struct vnode *a_fdvp;
35954692Sbostic 		struct vnode *a_fvp;
36054692Sbostic 		struct componentname *a_fcnp;
36154692Sbostic 		struct vnode *a_tdvp;
36254692Sbostic 		struct vnode *a_tvp;
36354692Sbostic 		struct componentname *a_tcnp;
36454692Sbostic 	} */ *ap;
36554264Sbostic {
36654264Sbostic 	int ret;
36754264Sbostic 
36854264Sbostic 	SET_DIROP(VTOI(ap->a_fdvp)->i_lfs);
36954264Sbostic 	MARK_VNODE(ap->a_fdvp);
37054264Sbostic 	MARK_VNODE(ap->a_tdvp);
37154264Sbostic 	ret = ufs_rename(ap);
37254264Sbostic 	SET_ENDOP(VTOI(ap->a_fdvp)->i_lfs);
37354264Sbostic 	return (ret);
37454264Sbostic }
37555936Sbostic /* XXX hack to avoid calling ITIMES in getattr */
37655936Sbostic int
37755936Sbostic lfs_getattr(ap)
37855936Sbostic 	struct vop_getattr_args /* {
37955936Sbostic 		struct vnode *a_vp;
38055936Sbostic 		struct vattr *a_vap;
38155936Sbostic 		struct ucred *a_cred;
38255936Sbostic 		struct proc *a_p;
38355936Sbostic 	} */ *ap;
38455936Sbostic {
38555936Sbostic 	register struct vnode *vp = ap->a_vp;
38655936Sbostic 	register struct inode *ip = VTOI(vp);
38755936Sbostic 	register struct vattr *vap = ap->a_vap;
38855936Sbostic 	/*
38955936Sbostic 	 * Copy from inode table
39055936Sbostic 	 */
39155936Sbostic 	vap->va_fsid = ip->i_dev;
39255936Sbostic 	vap->va_fileid = ip->i_number;
39355936Sbostic 	vap->va_mode = ip->i_mode & ~IFMT;
39455936Sbostic 	vap->va_nlink = ip->i_nlink;
39555936Sbostic 	vap->va_uid = ip->i_uid;
39655936Sbostic 	vap->va_gid = ip->i_gid;
39755936Sbostic 	vap->va_rdev = (dev_t)ip->i_rdev;
39855936Sbostic 	vap->va_size = ip->i_din.di_size;
39955936Sbostic 	vap->va_atime = ip->i_atime;
40055936Sbostic 	vap->va_mtime = ip->i_mtime;
40155936Sbostic 	vap->va_ctime = ip->i_ctime;
40255936Sbostic 	vap->va_flags = ip->i_flags;
40355936Sbostic 	vap->va_gen = ip->i_gen;
40455936Sbostic 	/* this doesn't belong here */
40555936Sbostic 	if (vp->v_type == VBLK)
40655936Sbostic 		vap->va_blocksize = BLKDEV_IOSIZE;
40755936Sbostic 	else if (vp->v_type == VCHR)
40855936Sbostic 		vap->va_blocksize = MAXBSIZE;
40955936Sbostic 	else
41055936Sbostic 		vap->va_blocksize = vp->v_mount->mnt_stat.f_iosize;
41155936Sbostic 	vap->va_bytes = dbtob(ip->i_blocks);
41255936Sbostic 	vap->va_type = vp->v_type;
41355936Sbostic 	vap->va_filerev = ip->i_modrev;
41455936Sbostic 	return (0);
41555936Sbostic }
41656053Sbostic /*
41756053Sbostic  * Close called
41856053Sbostic  *
41956053Sbostic  * XXX -- we were using ufs_close, but since it updates the
42056053Sbostic  * times on the inode, we might need to bump the uinodes
42156053Sbostic  * count.
42256053Sbostic  */
42356053Sbostic /* ARGSUSED */
42456053Sbostic int
42556053Sbostic lfs_close(ap)
42656053Sbostic 	struct vop_close_args /* {
42756053Sbostic 		struct vnode *a_vp;
42856053Sbostic 		int  a_fflag;
42956053Sbostic 		struct ucred *a_cred;
43056053Sbostic 		struct proc *a_p;
43156053Sbostic 	} */ *ap;
43256053Sbostic {
43356053Sbostic 	register struct vnode *vp = ap->a_vp;
43456053Sbostic 	register struct inode *ip = VTOI(vp);
43556053Sbostic 	int mod;
43656053Sbostic 
437*64608Sbostic 	if (vp->v_usecount > 1 && !(ip->i_flag & IN_LOCKED)) {
438*64608Sbostic 		mod = ip->i_flag & IN_MODIFIED;
43956053Sbostic 		ITIMES(ip, &time, &time);
440*64608Sbostic 		if (!mod && ip->i_flag & IN_MODIFIED)
44156053Sbostic 			ip->i_lfs->lfs_uinodes++;
44256053Sbostic 	}
44356053Sbostic 	return (0);
44456053Sbostic }
44556053Sbostic 
446