xref: /csrg-svn/sys/ufs/lfs/lfs_vnops.c (revision 69811)
123405Smckusick /*
269418Smckusick  * Copyright (c) 1986, 1989, 1991, 1993, 1995
363375Sbostic  *	The Regents of the University of California.  All rights reserved.
423405Smckusick  *
544539Sbostic  * %sccs.include.redist.c%
637737Smckusick  *
7*69811Smargo  *	@(#)lfs_vnops.c	8.13 (Berkeley) 06/10/95
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 */
4467575Spendry 	{ &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 */
5367648Smckusick 	{ &vop_lease_desc, ufs_lease_check },		/* lease */
5454030Smckusick 	{ &vop_ioctl_desc, ufs_ioctl },			/* ioctl */
5553533Sheideman 	{ &vop_select_desc, ufs_select },		/* select */
5668409Smckusick 	{ &vop_revoke_desc, ufs_revoke },		/* revoke */
5754030Smckusick 	{ &vop_mmap_desc, ufs_mmap },			/* mmap */
5854030Smckusick 	{ &vop_fsync_desc, lfs_fsync },			/* fsync */
5954030Smckusick 	{ &vop_seek_desc, ufs_seek },			/* seek */
6057067Smargo 	{ &vop_remove_desc, ufs_remove },		/* remove */
6157067Smargo 	{ &vop_link_desc, ufs_link },			/* link */
6257067Smargo 	{ &vop_rename_desc, ufs_rename },		/* rename */
6357067Smargo 	{ &vop_mkdir_desc, ufs_mkdir },			/* mkdir */
6457067Smargo 	{ &vop_rmdir_desc, ufs_rmdir },			/* rmdir */
6557067Smargo 	{ &vop_symlink_desc, ufs_symlink },		/* symlink */
6653533Sheideman 	{ &vop_readdir_desc, ufs_readdir },		/* readdir */
6753533Sheideman 	{ &vop_readlink_desc, ufs_readlink },		/* readlink */
6853533Sheideman 	{ &vop_abortop_desc, ufs_abortop },		/* abortop */
69*69811Smargo 	{ &vop_inactive_desc, ufs_inactive },		/* inactive */
7067411Smckusick 	{ &vop_reclaim_desc, lfs_reclaim },		/* reclaim */
7154030Smckusick 	{ &vop_lock_desc, ufs_lock },			/* lock */
7253533Sheideman 	{ &vop_unlock_desc, ufs_unlock },		/* unlock */
7356474Smargo 	{ &vop_bmap_desc, ufs_bmap },			/* bmap */
7453533Sheideman 	{ &vop_strategy_desc, ufs_strategy },		/* strategy */
7554030Smckusick 	{ &vop_print_desc, ufs_print },			/* print */
7653533Sheideman 	{ &vop_islocked_desc, ufs_islocked },		/* islocked */
7760395Smckusick 	{ &vop_pathconf_desc, ufs_pathconf },		/* pathconf */
7853533Sheideman 	{ &vop_advlock_desc, ufs_advlock },		/* advlock */
7953533Sheideman 	{ &vop_blkatoff_desc, lfs_blkatoff },		/* blkatoff */
8053533Sheideman 	{ &vop_valloc_desc, lfs_valloc },		/* valloc */
8154030Smckusick 	{ &vop_vfree_desc, lfs_vfree },			/* vfree */
8253533Sheideman 	{ &vop_truncate_desc, lfs_truncate },		/* truncate */
8353533Sheideman 	{ &vop_update_desc, lfs_update },		/* update */
8453533Sheideman 	{ &vop_bwrite_desc, lfs_bwrite },		/* bwrite */
8553533Sheideman 	{ (struct vnodeop_desc*)NULL, (int(*)())NULL }
8651482Sbostic };
8753533Sheideman struct vnodeopv_desc lfs_vnodeop_opv_desc =
8853533Sheideman 	{ &lfs_vnodeop_p, lfs_vnodeop_entries };
896254Sroot 
9053533Sheideman int (**lfs_specop_p)();
9153533Sheideman struct vnodeopv_entry_desc lfs_specop_entries[] = {
9253533Sheideman 	{ &vop_default_desc, vn_default_error },
9353533Sheideman 	{ &vop_lookup_desc, spec_lookup },		/* lookup */
9453533Sheideman 	{ &vop_create_desc, spec_create },		/* create */
9553533Sheideman 	{ &vop_mknod_desc, spec_mknod },		/* mknod */
9654030Smckusick 	{ &vop_open_desc, spec_open },			/* open */
9753533Sheideman 	{ &vop_close_desc, ufsspec_close },		/* close */
9853533Sheideman 	{ &vop_access_desc, ufs_access },		/* access */
9955936Sbostic 	{ &vop_getattr_desc, lfs_getattr },		/* getattr */
10053533Sheideman 	{ &vop_setattr_desc, ufs_setattr },		/* setattr */
10153533Sheideman 	{ &vop_read_desc, ufsspec_read },		/* read */
10253533Sheideman 	{ &vop_write_desc, ufsspec_write },		/* write */
10367648Smckusick 	{ &vop_lease_desc, spec_lease_check },		/* lease */
10453533Sheideman 	{ &vop_ioctl_desc, spec_ioctl },		/* ioctl */
10553533Sheideman 	{ &vop_select_desc, spec_select },		/* select */
10668409Smckusick 	{ &vop_revoke_desc, spec_revoke },		/* revoke */
10754030Smckusick 	{ &vop_mmap_desc, spec_mmap },			/* mmap */
10853533Sheideman 	{ &vop_fsync_desc, spec_fsync },		/* fsync */
10954030Smckusick 	{ &vop_seek_desc, spec_seek },			/* seek */
11053533Sheideman 	{ &vop_remove_desc, spec_remove },		/* remove */
11154030Smckusick 	{ &vop_link_desc, spec_link },			/* link */
11253533Sheideman 	{ &vop_rename_desc, spec_rename },		/* rename */
11353533Sheideman 	{ &vop_mkdir_desc, spec_mkdir },		/* mkdir */
11453533Sheideman 	{ &vop_rmdir_desc, spec_rmdir },		/* rmdir */
11553533Sheideman 	{ &vop_symlink_desc, spec_symlink },		/* symlink */
11653533Sheideman 	{ &vop_readdir_desc, spec_readdir },		/* readdir */
11753533Sheideman 	{ &vop_readlink_desc, spec_readlink },		/* readlink */
11853533Sheideman 	{ &vop_abortop_desc, spec_abortop },		/* abortop */
119*69811Smargo 	{ &vop_inactive_desc, ufs_inactive },		/* inactive */
12067411Smckusick 	{ &vop_reclaim_desc, lfs_reclaim },		/* reclaim */
12154030Smckusick 	{ &vop_lock_desc, ufs_lock },			/* lock */
12253533Sheideman 	{ &vop_unlock_desc, ufs_unlock },		/* unlock */
12354030Smckusick 	{ &vop_bmap_desc, spec_bmap },			/* bmap */
12453533Sheideman 	{ &vop_strategy_desc, spec_strategy },		/* strategy */
12554030Smckusick 	{ &vop_print_desc, ufs_print },			/* print */
12653533Sheideman 	{ &vop_islocked_desc, ufs_islocked },		/* islocked */
12760395Smckusick 	{ &vop_pathconf_desc, spec_pathconf },		/* pathconf */
12853533Sheideman 	{ &vop_advlock_desc, spec_advlock },		/* advlock */
12953533Sheideman 	{ &vop_blkatoff_desc, spec_blkatoff },		/* blkatoff */
13053533Sheideman 	{ &vop_valloc_desc, spec_valloc },		/* valloc */
13154030Smckusick 	{ &vop_vfree_desc, lfs_vfree },			/* vfree */
13253533Sheideman 	{ &vop_truncate_desc, spec_truncate },		/* truncate */
13353533Sheideman 	{ &vop_update_desc, lfs_update },		/* update */
13453533Sheideman 	{ &vop_bwrite_desc, lfs_bwrite },		/* bwrite */
13553533Sheideman 	{ (struct vnodeop_desc*)NULL, (int(*)())NULL }
13651558Smckusick };
13753533Sheideman struct vnodeopv_desc lfs_specop_opv_desc =
13853533Sheideman 	{ &lfs_specop_p, lfs_specop_entries };
13951558Smckusick 
14051558Smckusick #ifdef FIFO
14153533Sheideman int (**lfs_fifoop_p)();
14253533Sheideman struct vnodeopv_entry_desc lfs_fifoop_entries[] = {
14353533Sheideman 	{ &vop_default_desc, vn_default_error },
14453533Sheideman 	{ &vop_lookup_desc, fifo_lookup },		/* lookup */
14553533Sheideman 	{ &vop_create_desc, fifo_create },		/* create */
14653533Sheideman 	{ &vop_mknod_desc, fifo_mknod },		/* mknod */
14754030Smckusick 	{ &vop_open_desc, fifo_open },			/* open */
14853533Sheideman 	{ &vop_close_desc, ufsfifo_close },		/* close */
14953533Sheideman 	{ &vop_access_desc, ufs_access },		/* access */
15055936Sbostic 	{ &vop_getattr_desc, lfs_getattr },		/* getattr */
15153533Sheideman 	{ &vop_setattr_desc, ufs_setattr },		/* setattr */
15253533Sheideman 	{ &vop_read_desc, ufsfifo_read },		/* read */
15353533Sheideman 	{ &vop_write_desc, ufsfifo_write },		/* write */
15467648Smckusick 	{ &vop_lease_desc, fifo_lease_check },		/* lease */
15553533Sheideman 	{ &vop_ioctl_desc, fifo_ioctl },		/* ioctl */
15653533Sheideman 	{ &vop_select_desc, fifo_select },		/* select */
15768409Smckusick 	{ &vop_revoke_desc, fifo_revoke },		/* revoke */
15854030Smckusick 	{ &vop_mmap_desc, fifo_mmap },			/* mmap */
15953533Sheideman 	{ &vop_fsync_desc, fifo_fsync },		/* fsync */
16054030Smckusick 	{ &vop_seek_desc, fifo_seek },			/* seek */
16153533Sheideman 	{ &vop_remove_desc, fifo_remove },		/* remove */
16254030Smckusick 	{ &vop_link_desc, fifo_link },			/* link */
16353533Sheideman 	{ &vop_rename_desc, fifo_rename },		/* rename */
16453533Sheideman 	{ &vop_mkdir_desc, fifo_mkdir },		/* mkdir */
16553533Sheideman 	{ &vop_rmdir_desc, fifo_rmdir },		/* rmdir */
16653533Sheideman 	{ &vop_symlink_desc, fifo_symlink },		/* symlink */
16753533Sheideman 	{ &vop_readdir_desc, fifo_readdir },		/* readdir */
16853533Sheideman 	{ &vop_readlink_desc, fifo_readlink },		/* readlink */
16953533Sheideman 	{ &vop_abortop_desc, fifo_abortop },		/* abortop */
170*69811Smargo 	{ &vop_inactive_desc, ufs_inactive },		/* inactive */
17167411Smckusick 	{ &vop_reclaim_desc, lfs_reclaim },		/* reclaim */
17254030Smckusick 	{ &vop_lock_desc, ufs_lock },			/* lock */
17353533Sheideman 	{ &vop_unlock_desc, ufs_unlock },		/* unlock */
17454030Smckusick 	{ &vop_bmap_desc, fifo_bmap },			/* bmap */
17553533Sheideman 	{ &vop_strategy_desc, fifo_strategy },		/* strategy */
17654030Smckusick 	{ &vop_print_desc, ufs_print },			/* print */
17753533Sheideman 	{ &vop_islocked_desc, ufs_islocked },		/* islocked */
17860395Smckusick 	{ &vop_pathconf_desc, fifo_pathconf },		/* pathconf */
17953533Sheideman 	{ &vop_advlock_desc, fifo_advlock },		/* advlock */
18053533Sheideman 	{ &vop_blkatoff_desc, fifo_blkatoff },		/* blkatoff */
18153533Sheideman 	{ &vop_valloc_desc, fifo_valloc },		/* valloc */
18254030Smckusick 	{ &vop_vfree_desc, lfs_vfree },			/* vfree */
18353533Sheideman 	{ &vop_truncate_desc, fifo_truncate },		/* truncate */
18453533Sheideman 	{ &vop_update_desc, lfs_update },		/* update */
18553533Sheideman 	{ &vop_bwrite_desc, lfs_bwrite },		/* bwrite */
18653533Sheideman 	{ (struct vnodeop_desc*)NULL, (int(*)())NULL }
18751558Smckusick };
18853533Sheideman struct vnodeopv_desc lfs_fifoop_opv_desc =
18953533Sheideman 	{ &lfs_fifoop_p, lfs_fifoop_entries };
19051558Smckusick #endif /* FIFO */
19151558Smckusick 
19264417Sbostic #define	LFS_READWRITE
19364417Sbostic #include <ufs/ufs/ufs_readwrite.c>
19464417Sbostic #undef	LFS_READWRITE
19539608Smckusick 
19639608Smckusick /*
19737737Smckusick  * Synch an open file.
1989167Ssam  */
19937737Smckusick /* ARGSUSED */
20054030Smckusick lfs_fsync(ap)
20154692Sbostic 	struct vop_fsync_args /* {
20254692Sbostic 		struct vnode *a_vp;
20354692Sbostic 		struct ucred *a_cred;
20454692Sbostic 		int a_waitfor;
20554692Sbostic 		struct proc *a_p;
20654692Sbostic 	} */ *ap;
2077701Ssam {
20854765Smckusick 	struct timeval tv;
2097701Ssam 
21054765Smckusick 	tv = time;
21155547Sbostic 	return (VOP_UPDATE(ap->a_vp, &tv, &tv,
21255547Sbostic 	    ap->a_waitfor == MNT_WAIT ? LFS_SYNC : 0));
21337737Smckusick }
21451558Smckusick 
21551558Smckusick /*
21654264Sbostic  * These macros are used to bracket UFS directory ops, so that we can
21754264Sbostic  * identify all the pages touched during directory ops which need to
21854264Sbostic  * be ordered and flushed atomically, so that they may be recovered.
21954264Sbostic  */
22054264Sbostic #define	SET_DIROP(fs) {							\
22154264Sbostic 	if ((fs)->lfs_writer)						\
22255547Sbostic 		tsleep(&(fs)->lfs_dirops, PRIBIO + 1, "lfs_dirop", 0);	\
22354264Sbostic 	++(fs)->lfs_dirops;						\
22454264Sbostic 	(fs)->lfs_doifile = 1;						\
22554264Sbostic }
22654264Sbostic 
22754264Sbostic #define	SET_ENDOP(fs) {							\
22854264Sbostic 	--(fs)->lfs_dirops;						\
22954264Sbostic 	if (!(fs)->lfs_dirops)						\
23054264Sbostic 		wakeup(&(fs)->lfs_writer);				\
23154264Sbostic }
23254264Sbostic 
23354264Sbostic #define	MARK_VNODE(dvp)	(dvp)->v_flag |= VDIROP
23454264Sbostic 
23554264Sbostic int
lfs_symlink(ap)23654264Sbostic lfs_symlink(ap)
23754692Sbostic 	struct vop_symlink_args /* {
23854692Sbostic 		struct vnode *a_dvp;
23954692Sbostic 		struct vnode **a_vpp;
24054692Sbostic 		struct componentname *a_cnp;
24154692Sbostic 		struct vattr *a_vap;
24254692Sbostic 		char *a_target;
24354692Sbostic 	} */ *ap;
24454264Sbostic {
24554264Sbostic 	int ret;
24654264Sbostic 
24754264Sbostic 	SET_DIROP(VTOI(ap->a_dvp)->i_lfs);
24854264Sbostic 	MARK_VNODE(ap->a_dvp);
24954264Sbostic 	ret = ufs_symlink(ap);
25054264Sbostic 	SET_ENDOP(VTOI(ap->a_dvp)->i_lfs);
25154264Sbostic 	return (ret);
25254264Sbostic }
25354264Sbostic 
25454264Sbostic int
lfs_mknod(ap)25554264Sbostic lfs_mknod(ap)
25654692Sbostic 	struct vop_mknod_args /* {
25754692Sbostic 		struct vnode *a_dvp;
25854692Sbostic 		struct vnode **a_vpp;
25954692Sbostic 		struct componentname *a_cnp;
26054692Sbostic 		struct vattr *a_vap;
26154692Sbostic 	} */ *ap;
26254264Sbostic {
26354264Sbostic 	int ret;
26454264Sbostic 
26554264Sbostic 	SET_DIROP(VTOI(ap->a_dvp)->i_lfs);
26654264Sbostic 	MARK_VNODE(ap->a_dvp);
26754264Sbostic 	ret = ufs_mknod(ap);
26854264Sbostic 	SET_ENDOP(VTOI(ap->a_dvp)->i_lfs);
26954264Sbostic 	return (ret);
27054264Sbostic }
27154264Sbostic 
27254264Sbostic int
lfs_create(ap)27354264Sbostic lfs_create(ap)
27454692Sbostic 	struct vop_create_args /* {
27554692Sbostic 		struct vnode *a_dvp;
27654692Sbostic 		struct vnode **a_vpp;
27754692Sbostic 		struct componentname *a_cnp;
27854692Sbostic 		struct vattr *a_vap;
27954692Sbostic 	} */ *ap;
28054264Sbostic {
28154264Sbostic 	int ret;
28254264Sbostic 
28354264Sbostic 	SET_DIROP(VTOI(ap->a_dvp)->i_lfs);
28454264Sbostic 	MARK_VNODE(ap->a_dvp);
28554264Sbostic 	ret = ufs_create(ap);
28654264Sbostic 	SET_ENDOP(VTOI(ap->a_dvp)->i_lfs);
28754264Sbostic 	return (ret);
28854264Sbostic }
28954264Sbostic 
29054264Sbostic int
lfs_mkdir(ap)29154264Sbostic lfs_mkdir(ap)
29254692Sbostic 	struct vop_mkdir_args /* {
29354692Sbostic 		struct vnode *a_dvp;
29454692Sbostic 		struct vnode **a_vpp;
29554692Sbostic 		struct componentname *a_cnp;
29654692Sbostic 		struct vattr *a_vap;
29754692Sbostic 	} */ *ap;
29854264Sbostic {
29954264Sbostic 	int ret;
30054264Sbostic 
30154264Sbostic 	SET_DIROP(VTOI(ap->a_dvp)->i_lfs);
30254264Sbostic 	MARK_VNODE(ap->a_dvp);
30354264Sbostic 	ret = ufs_mkdir(ap);
30454264Sbostic 	SET_ENDOP(VTOI(ap->a_dvp)->i_lfs);
30554264Sbostic 	return (ret);
30654264Sbostic }
30754264Sbostic 
30854264Sbostic int
lfs_remove(ap)30954264Sbostic lfs_remove(ap)
31054692Sbostic 	struct vop_remove_args /* {
31154692Sbostic 		struct vnode *a_dvp;
31254692Sbostic 		struct vnode *a_vp;
31354692Sbostic 		struct componentname *a_cnp;
31454692Sbostic 	} */ *ap;
31554264Sbostic {
31654264Sbostic 	int ret;
31754264Sbostic 
31854264Sbostic 	SET_DIROP(VTOI(ap->a_dvp)->i_lfs);
31954264Sbostic 	MARK_VNODE(ap->a_dvp);
32054264Sbostic 	MARK_VNODE(ap->a_vp);
32154264Sbostic 	ret = ufs_remove(ap);
32254264Sbostic 	SET_ENDOP(VTOI(ap->a_dvp)->i_lfs);
32354264Sbostic 	return (ret);
32454264Sbostic }
32554264Sbostic 
32654264Sbostic int
lfs_rmdir(ap)32754264Sbostic lfs_rmdir(ap)
32854692Sbostic 	struct vop_rmdir_args /* {
32954692Sbostic 		struct vnodeop_desc *a_desc;
33054692Sbostic 		struct vnode *a_dvp;
33154692Sbostic 		struct vnode *a_vp;
33254692Sbostic 		struct componentname *a_cnp;
33354692Sbostic 	} */ *ap;
33454264Sbostic {
33554264Sbostic 	int ret;
33654264Sbostic 
33754264Sbostic 	SET_DIROP(VTOI(ap->a_dvp)->i_lfs);
33854264Sbostic 	MARK_VNODE(ap->a_dvp);
33954264Sbostic 	MARK_VNODE(ap->a_vp);
34054264Sbostic 	ret = ufs_rmdir(ap);
34154264Sbostic 	SET_ENDOP(VTOI(ap->a_dvp)->i_lfs);
34254264Sbostic 	return (ret);
34354264Sbostic }
34454264Sbostic 
34554264Sbostic int
lfs_link(ap)34654264Sbostic lfs_link(ap)
34754692Sbostic 	struct vop_link_args /* {
34854692Sbostic 		struct vnode *a_vp;
34954692Sbostic 		struct vnode *a_tdvp;
35054692Sbostic 		struct componentname *a_cnp;
35154692Sbostic 	} */ *ap;
35254264Sbostic {
35354264Sbostic 	int ret;
35454264Sbostic 
35568536Smckusick 	SET_DIROP(VTOI(ap->a_tdvp)->i_lfs);
35668536Smckusick 	MARK_VNODE(ap->a_tdvp);
35754264Sbostic 	ret = ufs_link(ap);
35868536Smckusick 	SET_ENDOP(VTOI(ap->a_tdvp)->i_lfs);
35954264Sbostic 	return (ret);
36054264Sbostic }
36154264Sbostic 
36254264Sbostic int
lfs_rename(ap)36354264Sbostic lfs_rename(ap)
36454692Sbostic 	struct vop_rename_args  /* {
36554692Sbostic 		struct vnode *a_fdvp;
36654692Sbostic 		struct vnode *a_fvp;
36754692Sbostic 		struct componentname *a_fcnp;
36854692Sbostic 		struct vnode *a_tdvp;
36954692Sbostic 		struct vnode *a_tvp;
37054692Sbostic 		struct componentname *a_tcnp;
37154692Sbostic 	} */ *ap;
37254264Sbostic {
37354264Sbostic 	int ret;
37454264Sbostic 
37554264Sbostic 	SET_DIROP(VTOI(ap->a_fdvp)->i_lfs);
37654264Sbostic 	MARK_VNODE(ap->a_fdvp);
37754264Sbostic 	MARK_VNODE(ap->a_tdvp);
37854264Sbostic 	ret = ufs_rename(ap);
37954264Sbostic 	SET_ENDOP(VTOI(ap->a_fdvp)->i_lfs);
38054264Sbostic 	return (ret);
38154264Sbostic }
38255936Sbostic /* XXX hack to avoid calling ITIMES in getattr */
38355936Sbostic int
lfs_getattr(ap)38455936Sbostic lfs_getattr(ap)
38555936Sbostic 	struct vop_getattr_args /* {
38655936Sbostic 		struct vnode *a_vp;
38755936Sbostic 		struct vattr *a_vap;
38855936Sbostic 		struct ucred *a_cred;
38955936Sbostic 		struct proc *a_p;
39055936Sbostic 	} */ *ap;
39155936Sbostic {
39255936Sbostic 	register struct vnode *vp = ap->a_vp;
39355936Sbostic 	register struct inode *ip = VTOI(vp);
39455936Sbostic 	register struct vattr *vap = ap->a_vap;
39555936Sbostic 	/*
39655936Sbostic 	 * Copy from inode table
39755936Sbostic 	 */
39855936Sbostic 	vap->va_fsid = ip->i_dev;
39955936Sbostic 	vap->va_fileid = ip->i_number;
40055936Sbostic 	vap->va_mode = ip->i_mode & ~IFMT;
40155936Sbostic 	vap->va_nlink = ip->i_nlink;
40255936Sbostic 	vap->va_uid = ip->i_uid;
40355936Sbostic 	vap->va_gid = ip->i_gid;
40455936Sbostic 	vap->va_rdev = (dev_t)ip->i_rdev;
40555936Sbostic 	vap->va_size = ip->i_din.di_size;
40668549Smckusick 	vap->va_atime.ts_sec = ip->i_atime;
40768549Smckusick 	vap->va_atime.ts_nsec = ip->i_atimensec;
40868549Smckusick 	vap->va_mtime.ts_sec = ip->i_mtime;
40968549Smckusick 	vap->va_mtime.ts_nsec = ip->i_mtimensec;
41068549Smckusick 	vap->va_ctime.ts_sec = ip->i_ctime;
41168549Smckusick 	vap->va_ctime.ts_nsec = ip->i_ctimensec;
41255936Sbostic 	vap->va_flags = ip->i_flags;
41355936Sbostic 	vap->va_gen = ip->i_gen;
41455936Sbostic 	/* this doesn't belong here */
41555936Sbostic 	if (vp->v_type == VBLK)
41655936Sbostic 		vap->va_blocksize = BLKDEV_IOSIZE;
41755936Sbostic 	else if (vp->v_type == VCHR)
41855936Sbostic 		vap->va_blocksize = MAXBSIZE;
41955936Sbostic 	else
42055936Sbostic 		vap->va_blocksize = vp->v_mount->mnt_stat.f_iosize;
42155936Sbostic 	vap->va_bytes = dbtob(ip->i_blocks);
42255936Sbostic 	vap->va_type = vp->v_type;
42355936Sbostic 	vap->va_filerev = ip->i_modrev;
42455936Sbostic 	return (0);
42555936Sbostic }
42656053Sbostic /*
42756053Sbostic  * Close called
42856053Sbostic  *
42956053Sbostic  * XXX -- we were using ufs_close, but since it updates the
43056053Sbostic  * times on the inode, we might need to bump the uinodes
43156053Sbostic  * count.
43256053Sbostic  */
43356053Sbostic /* ARGSUSED */
43456053Sbostic int
lfs_close(ap)43556053Sbostic lfs_close(ap)
43656053Sbostic 	struct vop_close_args /* {
43756053Sbostic 		struct vnode *a_vp;
43856053Sbostic 		int  a_fflag;
43956053Sbostic 		struct ucred *a_cred;
44056053Sbostic 		struct proc *a_p;
44156053Sbostic 	} */ *ap;
44256053Sbostic {
44356053Sbostic 	register struct vnode *vp = ap->a_vp;
44456053Sbostic 	register struct inode *ip = VTOI(vp);
44556053Sbostic 	int mod;
44656053Sbostic 
44769418Smckusick 	simple_lock(&vp->v_interlock);
44869418Smckusick 	if (vp->v_usecount > 1) {
44964608Sbostic 		mod = ip->i_flag & IN_MODIFIED;
45056053Sbostic 		ITIMES(ip, &time, &time);
45164608Sbostic 		if (!mod && ip->i_flag & IN_MODIFIED)
45256053Sbostic 			ip->i_lfs->lfs_uinodes++;
45356053Sbostic 	}
45469418Smckusick 	simple_unlock(&vp->v_interlock);
45556053Sbostic 	return (0);
45656053Sbostic }
45756053Sbostic 
45865239Smckusick /*
45967411Smckusick  * Reclaim an inode so that it can be used for other purposes.
46067411Smckusick  */
46167411Smckusick int
lfs_reclaim(ap)46267411Smckusick lfs_reclaim(ap)
46367411Smckusick 	struct vop_reclaim_args /* {
46467411Smckusick 		struct vnode *a_vp;
46569418Smckusick 		struct proc *a_p;
46667411Smckusick 	} */ *ap;
46767411Smckusick {
46867411Smckusick 	register struct vnode *vp = ap->a_vp;
46967411Smckusick 	int error;
47067411Smckusick 
47169418Smckusick 	if (error = ufs_reclaim(vp, ap->a_p))
47267411Smckusick 		return (error);
47367411Smckusick 	FREE(vp->v_data, M_LFSNODE);
47467411Smckusick 	vp->v_data = NULL;
47567411Smckusick 	return (0);
47667411Smckusick }
477