123399Smckusick /* 237736Smckusick * Copyright (c) 1982, 1986, 1989 Regents of the University of California. 337736Smckusick * All rights reserved. 423399Smckusick * 544537Sbostic * %sccs.include.redist.c% 637736Smckusick * 7*51484Sbostic * @(#)lfs_inode.c 7.45 (Berkeley) 11/01/91 823399Smckusick */ 924Sbill 10*51484Sbostic #include <sys/param.h> 11*51484Sbostic #include <sys/systm.h> 12*51484Sbostic #include <sys/mount.h> 13*51484Sbostic #include <sys/proc.h> 14*51484Sbostic #include <sys/file.h> 15*51484Sbostic #include <sys/buf.h> 16*51484Sbostic #include <sys/vnode.h> 17*51484Sbostic #include <sys/kernel.h> 18*51484Sbostic #include <sys/malloc.h> 1924Sbill 20*51484Sbostic #include <ufs/quota.h> 21*51484Sbostic #include <ufs/inode.h> 22*51484Sbostic #include <ufs/ufsmount.h> 23*51484Sbostic #include <ufs/ufs_extern.h> 2447571Skarels 25*51484Sbostic #include <lfs/lfs.h> 26*51484Sbostic #include <lfs/lfs_extern.h> 2724Sbill 2851155Sbostic extern int prtactive; /* 1 => print out reclaim of active vnodes */ 2939574Smckusick 3051346Sbostic int 3151155Sbostic lfs_init() 3224Sbill { 33*51484Sbostic return (ufs_init()); 3424Sbill } 3524Sbill 3624Sbill /* 37*51484Sbostic * Look up an LFS dinode number to find its incore vnode. If not already 38*51484Sbostic * in core, read it in from the specified device. Return the inode locked. 39*51484Sbostic * Detection and handling of mount points must be done by the calling routine. 4024Sbill */ 4151346Sbostic int 42*51484Sbostic lfs_iget(pip, ino, ipp) 43*51484Sbostic struct inode *pip; 444818Swnj ino_t ino; 4537736Smckusick struct inode **ipp; 4624Sbill { 47*51484Sbostic register LFS *fs; 48*51484Sbostic register struct inode *ip; 4937736Smckusick register struct vnode *vp; 50*51484Sbostic struct buf *bp; 51*51484Sbostic struct inode *nip; 52*51484Sbostic struct mount *mntp; 5339440Smckusick struct vnode *nvp; 54*51484Sbostic dev_t dev; 5551346Sbostic int error; 5624Sbill 5751155Sbostic printf("lfs_iget ino %d\n", ino); 5851155Sbostic 59*51484Sbostic if (ino < ROOTINO) 60*51484Sbostic return (EINVAL); 61*51484Sbostic 62*51484Sbostic dev = pip->i_dev; 63*51484Sbostic if ((*ipp = ufs_ihashget(dev, ino)) != NULL) 64*51484Sbostic return (0); 65*51484Sbostic 6651155Sbostic /* Allocate new vnode/inode. */ 67*51484Sbostic mntp = ITOV(pip)->v_mount; 6851155Sbostic error = lfs_vcreate(mntp, ino, &nvp); 6951155Sbostic if (error) { 70*51484Sbostic *ipp = NULL; 7137736Smckusick return (error); 7237736Smckusick } 7339440Smckusick ip = VTOI(nvp); 7451155Sbostic 7537736Smckusick /* 7639440Smckusick * Put it onto its hash chain and lock it so that other requests for 7739440Smckusick * this inode will block if they arrive while we are sleeping waiting 7839440Smckusick * for old data structures to be purged or for the contents of the 7939440Smckusick * disk portion of this inode to be read. 8039440Smckusick */ 81*51484Sbostic ufs_ihashins(ip); 8251155Sbostic 83*51484Sbostic /* Read in the disk contents for the inode, copy into the inode. */ 84*51484Sbostic fs = VFSTOUFS(mntp)->um_lfs; 85*51484Sbostic if (error = bread(VFSTOUFS(mntp)->um_devvp, lfs_itod(fs, ino), 86*51484Sbostic (int)fs->lfs_bsize, NOCRED, &bp)) { 8737736Smckusick /* 8841334Smckusick * The inode does not contain anything useful, so it would 89*51484Sbostic * be misleading to leave it on its hash chain. Iput() will 90*51484Sbostic * take care of putting it back on the free list. 9141334Smckusick */ 9241334Smckusick remque(ip); 9341334Smckusick ip->i_forw = ip; 9441334Smckusick ip->i_back = ip; 95*51484Sbostic 96*51484Sbostic /* Unlock and discard unneeded inode. */ 97*51484Sbostic ufs_iput(ip); 9837736Smckusick brelse(bp); 99*51484Sbostic *ipp = NULL; 10039440Smckusick return (error); 10137736Smckusick } 10251155Sbostic ip->i_din = *lfs_ifind(fs, ino, bp->b_un.b_dino); 10339440Smckusick brelse(bp); 10451155Sbostic 105*51484Sbostic /* Initialize the vnode from the inode, check for aliases. */ 106*51484Sbostic if (error = ufs_vinit(mntp, ip, &nip)) { 107*51484Sbostic ufs_iput(ip); 108*51484Sbostic *ipp = NULL; 109*51484Sbostic return (error); 11040289Smckusick } 111*51484Sbostic *ipp = nip; 11237736Smckusick return (0); 11337736Smckusick } 1147334Skre 11551346Sbostic int 116*51484Sbostic lfs_iupdat(ip, ta, tm, waitfor) 117*51484Sbostic register struct inode *ip; 118*51484Sbostic struct timeval *ta, *tm; 119*51484Sbostic int waitfor; 1207118Smckusick { 12138452Smckusick /* 122*51484Sbostic * XXX 123*51484Sbostic * This isn't right, but ufs_iupdat() isn't either. 12438452Smckusick */ 125*51484Sbostic ITIMES(ip, ta, tm); 126*51484Sbostic return (0); 12724Sbill } 12824Sbill 12924Sbill /* 130*51484Sbostic * Truncate the inode ip to at most length size. 13110736Ssam * 13210736Ssam * NB: triple indirect blocks are untested. 13324Sbill */ 134*51484Sbostic /* ARGSUSED */ 135*51484Sbostic int 13651155Sbostic lfs_itrunc(oip, length, flags) 13717942Smckusick register struct inode *oip; 1389165Ssam u_long length; 13939676Smckusick int flags; 14024Sbill { 141*51484Sbostic register LFS *fs; 14217942Smckusick struct buf *bp; 143*51484Sbostic daddr_t lbn; 144*51484Sbostic int error, offset, size; 1459165Ssam 14645721Smckusick vnode_pager_setsize(ITOV(oip), length); 147*51484Sbostic 148*51484Sbostic /* If length is larger than the file, just update the times. */ 14913000Ssam if (oip->i_size <= length) { 15013000Ssam oip->i_flag |= ICHG|IUPD; 15151183Sbostic ITIMES(oip, &time, &time); 15251183Sbostic return (0); 15313000Ssam } 154*51484Sbostic 1551203Sbill /* 156*51484Sbostic * Update the size of the file. If the file is not being truncated to 157*51484Sbostic * a block boundry, the contents of the partial block following the end 158*51484Sbostic * of the file must be zero'ed in case it ever become accessable again 159*51484Sbostic * because of subsequent file growth. 1601203Sbill */ 161*51484Sbostic fs = oip->i_lfs; 16217942Smckusick offset = blkoff(fs, length); 163*51484Sbostic if (offset == 0) 16417942Smckusick oip->i_size = length; 165*51484Sbostic else { 16617942Smckusick lbn = lblkno(fs, length); 16741313Smckusick #ifdef QUOTA 16841313Smckusick if (error = getinoquota(oip)) 16941313Smckusick return (error); 17051183Sbostic #endif 17151183Sbostic if (error = bread(ITOV(oip), lbn, fs->lfs_bsize, NOCRED, &bp)) 17237736Smckusick return (error); 17317942Smckusick oip->i_size = length; 17451155Sbostic size = blksize(fs); /* LFS */ 17545721Smckusick (void) vnode_pager_uncache(ITOV(oip)); 17626272Skarels bzero(bp->b_un.b_addr + offset, (unsigned)(size - offset)); 17745112Smckusick allocbuf(bp, size); 17851183Sbostic lfs_bwrite(bp); 17917942Smckusick } 180*51484Sbostic /* BZERO INODE BLOCK POINTERS HERE, FOR CONSISTENCY XXX */ 18124Sbill } 182