* Copyright (c) 1986, 1989, 1991 Regents of the University of California.
* %sccs.include.redist.c%
* @(#)lfs_inode.c 7.48 (Berkeley) %G%
#include <ufs/ufs/quota.h>
#include <ufs/ufs/inode.h>
#include <ufs/ufs/ufsmount.h>
#include <ufs/ufs/ufs_extern.h>
#include <ufs/lfs/lfs_extern.h>
* Look up an LFS dinode number to find its incore vnode. If not already
* in core, read it in from the specified device. Return the inode locked.
* Detection and handling of mount points must be done by the calling routine.
register struct inode
*ip
;
if ((*vpp
= ufs_ihashget(dev
, ino
)) != NULL
)
/* Allocate new vnode/inode. */
if (error
= lfs_vcreate(mntp
, ino
, &vp
)) {
* Put it onto its hash chain and lock it so that other requests for
* this inode will block if they arrive while we are sleeping waiting
* for old data structures to be purged or for the contents of the
* disk portion of this inode to be read.
/* Read in the disk contents for the inode, copy into the inode. */
if (error
= bread(ump
->um_devvp
, lfs_itod(fs
, ino
),
(int)fs
->lfs_bsize
, NOCRED
, &bp
)) {
* The inode does not contain anything useful, so it would
* be misleading to leave it on its hash chain. Iput() will
* return it to the free list.
/* Unlock and discard unneeded inode. */
ip
->i_din
= *lfs_ifind(fs
, ino
, bp
->b_un
.b_dino
);
* Initialize the vnode from the inode, check for aliases. In all
* cases re-init ip, the underlying vnode/inode may have changed.
if (error
= ufs_vinit(mntp
, &lfs_specops
, LFS_FIFOOPS
, &vp
)) {
* Finish inode initialization now that aliasing has been resolved.
ip
->i_devvp
= ump
->um_devvp
;
lfs_update(vp
, ta
, tm
, waitfor
)
register struct vnode
*vp
;
if (vp
->v_mount
->mnt_flag
& MNT_RDONLY
)
if ((ip
->i_flag
& (IUPD
|IACC
|ICHG
|IMOD
)) == 0)
ip
->i_atime
= ta
->tv_sec
;
ip
->i_mtime
= tm
->tv_sec
;
ip
->i_ctime
= time
.tv_sec
;
ip
->i_flag
&= ~(IUPD
|IACC
|ICHG
|IMOD
);
* I'm not real sure what to do here; once we have fsync and partial
* segments working in the LFS context, this must be fixed to be
* correct. The contents of the inode have to be pushed back to
* stable storage; note that the ifile contains the access time of
* the inode and must be updated as well.
* Truncate the inode ip to at most length size.
* NB: triple indirect blocks are untested.
lfs_truncate(ovp
, length
, flags
)
register struct inode
*oip
;
vnode_pager_setsize(ovp
, length
);
/* If length is larger than the file, just update the times. */
if (oip
->i_size
<= length
) {
oip
->i_flag
|= ICHG
|IUPD
;
ITIMES(oip
, &time
, &time
);
* Update the size of the file. If the file is not being truncated to
* a block boundry, the contents of the partial block following the end
* of the file must be zero'ed in case it ever become accessable again
* because of subsequent file growth.
offset
= blkoff(fs
, length
);
lbn
= lblkno(fs
, length
);
if (error
= getinoquota(oip
))
if (error
= bread(ovp
, lbn
, fs
->lfs_bsize
, NOCRED
, &bp
))
size
= blksize(fs
); /* LFS */
(void) vnode_pager_uncache(ovp
);
bzero(bp
->b_un
.b_addr
+ offset
, (unsigned)(size
- offset
));
/* BZERO INODE BLOCK POINTERS HERE, FOR CONSISTENCY XXX */