123399Smckusick /* 2*51498Sbostic * Copyright (c) 1986, 1989, 1991 Regents of the University of California. 337736Smckusick * All rights reserved. 423399Smckusick * 544537Sbostic * %sccs.include.redist.c% 637736Smckusick * 7*51498Sbostic * @(#)lfs_inode.c 7.46 (Berkeley) 11/01/91 823399Smckusick */ 924Sbill 1051484Sbostic #include <sys/param.h> 1151484Sbostic #include <sys/systm.h> 1251484Sbostic #include <sys/mount.h> 1351484Sbostic #include <sys/proc.h> 1451484Sbostic #include <sys/file.h> 1551484Sbostic #include <sys/buf.h> 1651484Sbostic #include <sys/vnode.h> 1751484Sbostic #include <sys/kernel.h> 1851484Sbostic #include <sys/malloc.h> 1924Sbill 20*51498Sbostic #include <ufs/ufs/quota.h> 21*51498Sbostic #include <ufs/ufs/inode.h> 22*51498Sbostic #include <ufs/ufs/ufsmount.h> 23*51498Sbostic #include <ufs/ufs/ufs_extern.h> 2447571Skarels 25*51498Sbostic #include <ufs/lfs/lfs.h> 26*51498Sbostic #include <ufs/lfs/lfs_extern.h> 2724Sbill 2851346Sbostic int 2951155Sbostic lfs_init() 3024Sbill { 3151484Sbostic return (ufs_init()); 3224Sbill } 3324Sbill 3424Sbill /* 3551484Sbostic * Look up an LFS dinode number to find its incore vnode. If not already 3651484Sbostic * in core, read it in from the specified device. Return the inode locked. 3751484Sbostic * Detection and handling of mount points must be done by the calling routine. 3824Sbill */ 3951346Sbostic int 4051484Sbostic lfs_iget(pip, ino, ipp) 4151484Sbostic struct inode *pip; 424818Swnj ino_t ino; 4337736Smckusick struct inode **ipp; 4424Sbill { 45*51498Sbostic register struct lfs *fs; 4651484Sbostic register struct inode *ip; 4751484Sbostic struct buf *bp; 4851484Sbostic struct mount *mntp; 49*51498Sbostic struct vnode *vp; 5051484Sbostic dev_t dev; 5151346Sbostic int error; 5224Sbill 53*51498Sbostic mntp = ITOV(pip)->v_mount; 54*51498Sbostic fs = VFSTOUFS(mntp)->um_lfs; 5551484Sbostic if (ino < ROOTINO) 5651484Sbostic return (EINVAL); 5751484Sbostic 5851484Sbostic dev = pip->i_dev; 5951484Sbostic if ((*ipp = ufs_ihashget(dev, ino)) != NULL) 6051484Sbostic return (0); 6151484Sbostic 6251155Sbostic /* Allocate new vnode/inode. */ 63*51498Sbostic if (error = lfs_vcreate(mntp, ino, &vp)) { 6451484Sbostic *ipp = NULL; 6537736Smckusick return (error); 6637736Smckusick } 67*51498Sbostic ip = VTOI(vp); 6851155Sbostic 6937736Smckusick /* 7039440Smckusick * Put it onto its hash chain and lock it so that other requests for 7139440Smckusick * this inode will block if they arrive while we are sleeping waiting 7239440Smckusick * for old data structures to be purged or for the contents of the 7339440Smckusick * disk portion of this inode to be read. 7439440Smckusick */ 7551484Sbostic ufs_ihashins(ip); 7651155Sbostic 7751484Sbostic /* Read in the disk contents for the inode, copy into the inode. */ 7851484Sbostic if (error = bread(VFSTOUFS(mntp)->um_devvp, lfs_itod(fs, ino), 7951484Sbostic (int)fs->lfs_bsize, NOCRED, &bp)) { 8037736Smckusick /* 8141334Smckusick * The inode does not contain anything useful, so it would 8251484Sbostic * be misleading to leave it on its hash chain. Iput() will 83*51498Sbostic * return it to the free list. 8441334Smckusick */ 8541334Smckusick remque(ip); 8641334Smckusick ip->i_forw = ip; 8741334Smckusick ip->i_back = ip; 8851484Sbostic 8951484Sbostic /* Unlock and discard unneeded inode. */ 9051484Sbostic ufs_iput(ip); 9137736Smckusick brelse(bp); 9251484Sbostic *ipp = NULL; 9339440Smckusick return (error); 9437736Smckusick } 9551155Sbostic ip->i_din = *lfs_ifind(fs, ino, bp->b_un.b_dino); 9639440Smckusick brelse(bp); 9751155Sbostic 98*51498Sbostic /* 99*51498Sbostic * Initialize the vnode from the inode, check for aliases. In all 100*51498Sbostic * cases re-init ip, the underlying vnode/inode may have changed. 101*51498Sbostic */ 102*51498Sbostic if (error = ufs_vinit(mntp, &vp)) { 10351484Sbostic ufs_iput(ip); 10451484Sbostic *ipp = NULL; 10551484Sbostic return (error); 10640289Smckusick } 107*51498Sbostic *ipp = VTOI(vp); 10837736Smckusick return (0); 10937736Smckusick } 1107334Skre 11151346Sbostic int 11251484Sbostic lfs_iupdat(ip, ta, tm, waitfor) 11351484Sbostic register struct inode *ip; 11451484Sbostic struct timeval *ta, *tm; 11551484Sbostic int waitfor; 1167118Smckusick { 11738452Smckusick /* 11851484Sbostic * XXX 11951484Sbostic * This isn't right, but ufs_iupdat() isn't either. 12038452Smckusick */ 12151484Sbostic ITIMES(ip, ta, tm); 12251484Sbostic return (0); 12324Sbill } 12424Sbill 12524Sbill /* 12651484Sbostic * Truncate the inode ip to at most length size. 12710736Ssam * 12810736Ssam * NB: triple indirect blocks are untested. 12924Sbill */ 13051484Sbostic /* ARGSUSED */ 13151484Sbostic int 13251155Sbostic lfs_itrunc(oip, length, flags) 13317942Smckusick register struct inode *oip; 1349165Ssam u_long length; 13539676Smckusick int flags; 13624Sbill { 137*51498Sbostic register struct lfs *fs; 13817942Smckusick struct buf *bp; 13951484Sbostic daddr_t lbn; 14051484Sbostic int error, offset, size; 1419165Ssam 14245721Smckusick vnode_pager_setsize(ITOV(oip), length); 14351484Sbostic 14451484Sbostic /* If length is larger than the file, just update the times. */ 14513000Ssam if (oip->i_size <= length) { 14613000Ssam oip->i_flag |= ICHG|IUPD; 14751183Sbostic ITIMES(oip, &time, &time); 14851183Sbostic return (0); 14913000Ssam } 15051484Sbostic 1511203Sbill /* 15251484Sbostic * Update the size of the file. If the file is not being truncated to 15351484Sbostic * a block boundry, the contents of the partial block following the end 15451484Sbostic * of the file must be zero'ed in case it ever become accessable again 15551484Sbostic * because of subsequent file growth. 1561203Sbill */ 15751484Sbostic fs = oip->i_lfs; 15817942Smckusick offset = blkoff(fs, length); 15951484Sbostic if (offset == 0) 16017942Smckusick oip->i_size = length; 16151484Sbostic else { 16217942Smckusick lbn = lblkno(fs, length); 16341313Smckusick #ifdef QUOTA 16441313Smckusick if (error = getinoquota(oip)) 16541313Smckusick return (error); 16651183Sbostic #endif 16751183Sbostic if (error = bread(ITOV(oip), lbn, fs->lfs_bsize, NOCRED, &bp)) 16837736Smckusick return (error); 16917942Smckusick oip->i_size = length; 17051155Sbostic size = blksize(fs); /* LFS */ 17145721Smckusick (void) vnode_pager_uncache(ITOV(oip)); 17226272Skarels bzero(bp->b_un.b_addr + offset, (unsigned)(size - offset)); 17345112Smckusick allocbuf(bp, size); 17451183Sbostic lfs_bwrite(bp); 17517942Smckusick } 17651484Sbostic /* BZERO INODE BLOCK POINTERS HERE, FOR CONSISTENCY XXX */ 17724Sbill } 178