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