1 /* 2 * Copyright (c) 1986, 1989, 1991 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)lfs_inode.c 7.46 (Berkeley) 11/01/91 8 */ 9 10 #include <sys/param.h> 11 #include <sys/systm.h> 12 #include <sys/mount.h> 13 #include <sys/proc.h> 14 #include <sys/file.h> 15 #include <sys/buf.h> 16 #include <sys/vnode.h> 17 #include <sys/kernel.h> 18 #include <sys/malloc.h> 19 20 #include <ufs/ufs/quota.h> 21 #include <ufs/ufs/inode.h> 22 #include <ufs/ufs/ufsmount.h> 23 #include <ufs/ufs/ufs_extern.h> 24 25 #include <ufs/lfs/lfs.h> 26 #include <ufs/lfs/lfs_extern.h> 27 28 int 29 lfs_init() 30 { 31 return (ufs_init()); 32 } 33 34 /* 35 * Look up an LFS dinode number to find its incore vnode. If not already 36 * in core, read it in from the specified device. Return the inode locked. 37 * Detection and handling of mount points must be done by the calling routine. 38 */ 39 int 40 lfs_iget(pip, ino, ipp) 41 struct inode *pip; 42 ino_t ino; 43 struct inode **ipp; 44 { 45 register struct lfs *fs; 46 register struct inode *ip; 47 struct buf *bp; 48 struct mount *mntp; 49 struct vnode *vp; 50 dev_t dev; 51 int error; 52 53 mntp = ITOV(pip)->v_mount; 54 fs = VFSTOUFS(mntp)->um_lfs; 55 if (ino < ROOTINO) 56 return (EINVAL); 57 58 dev = pip->i_dev; 59 if ((*ipp = ufs_ihashget(dev, ino)) != NULL) 60 return (0); 61 62 /* Allocate new vnode/inode. */ 63 if (error = lfs_vcreate(mntp, ino, &vp)) { 64 *ipp = NULL; 65 return (error); 66 } 67 ip = VTOI(vp); 68 69 /* 70 * Put it onto its hash chain and lock it so that other requests for 71 * this inode will block if they arrive while we are sleeping waiting 72 * for old data structures to be purged or for the contents of the 73 * disk portion of this inode to be read. 74 */ 75 ufs_ihashins(ip); 76 77 /* Read in the disk contents for the inode, copy into the inode. */ 78 if (error = bread(VFSTOUFS(mntp)->um_devvp, lfs_itod(fs, ino), 79 (int)fs->lfs_bsize, NOCRED, &bp)) { 80 /* 81 * The inode does not contain anything useful, so it would 82 * be misleading to leave it on its hash chain. Iput() will 83 * return it to the free list. 84 */ 85 remque(ip); 86 ip->i_forw = ip; 87 ip->i_back = ip; 88 89 /* Unlock and discard unneeded inode. */ 90 ufs_iput(ip); 91 brelse(bp); 92 *ipp = NULL; 93 return (error); 94 } 95 ip->i_din = *lfs_ifind(fs, ino, bp->b_un.b_dino); 96 brelse(bp); 97 98 /* 99 * Initialize the vnode from the inode, check for aliases. In all 100 * cases re-init ip, the underlying vnode/inode may have changed. 101 */ 102 if (error = ufs_vinit(mntp, &vp)) { 103 ufs_iput(ip); 104 *ipp = NULL; 105 return (error); 106 } 107 *ipp = VTOI(vp); 108 return (0); 109 } 110 111 int 112 lfs_iupdat(ip, ta, tm, waitfor) 113 register struct inode *ip; 114 struct timeval *ta, *tm; 115 int waitfor; 116 { 117 /* 118 * XXX 119 * This isn't right, but ufs_iupdat() isn't either. 120 */ 121 ITIMES(ip, ta, tm); 122 return (0); 123 } 124 125 /* 126 * Truncate the inode ip to at most length size. 127 * 128 * NB: triple indirect blocks are untested. 129 */ 130 /* ARGSUSED */ 131 int 132 lfs_itrunc(oip, length, flags) 133 register struct inode *oip; 134 u_long length; 135 int flags; 136 { 137 register struct lfs *fs; 138 struct buf *bp; 139 daddr_t lbn; 140 int error, offset, size; 141 142 vnode_pager_setsize(ITOV(oip), length); 143 144 /* If length is larger than the file, just update the times. */ 145 if (oip->i_size <= length) { 146 oip->i_flag |= ICHG|IUPD; 147 ITIMES(oip, &time, &time); 148 return (0); 149 } 150 151 /* 152 * Update the size of the file. If the file is not being truncated to 153 * a block boundry, the contents of the partial block following the end 154 * of the file must be zero'ed in case it ever become accessable again 155 * because of subsequent file growth. 156 */ 157 fs = oip->i_lfs; 158 offset = blkoff(fs, length); 159 if (offset == 0) 160 oip->i_size = length; 161 else { 162 lbn = lblkno(fs, length); 163 #ifdef QUOTA 164 if (error = getinoquota(oip)) 165 return (error); 166 #endif 167 if (error = bread(ITOV(oip), lbn, fs->lfs_bsize, NOCRED, &bp)) 168 return (error); 169 oip->i_size = length; 170 size = blksize(fs); /* LFS */ 171 (void) vnode_pager_uncache(ITOV(oip)); 172 bzero(bp->b_un.b_addr + offset, (unsigned)(size - offset)); 173 allocbuf(bp, size); 174 lfs_bwrite(bp); 175 } 176 /* BZERO INODE BLOCK POINTERS HERE, FOR CONSISTENCY XXX */ 177 } 178