123394Smckusick /* 237735Smckusick * Copyright (c) 1982, 1986, 1989 Regents of the University of California. 334432Sbostic * All rights reserved. 423394Smckusick * 544536Sbostic * %sccs.include.redist.c% 634432Sbostic * 7*51183Sbostic * @(#)lfs_alloc.c 7.29 (Berkeley) 09/25/91 823394Smckusick */ 94359Smckusick 1017097Sbloom #include "param.h" 1151155Sbostic #include "kernel.h" 1217097Sbloom #include "buf.h" 1337735Smckusick #include "vnode.h" 1418307Sralph #include "syslog.h" 1551155Sbostic #include "../ufs/quota.h" 1651155Sbostic #include "../ufs/inode.h" 1751155Sbostic #include "mount.h" 1851155Sbostic #include "../ufs/ufsmount.h" 1951155Sbostic #include "lfs.h" 2051155Sbostic #include "lfs_extern.h" 214359Smckusick 2251155Sbostic #define LFS_IENTRY(I, F, IN, BP) \ 2351155Sbostic if (bread((F)->lfs_ivnode, (IN) / IFPB(F) + (F)->lfs_segtabsz, \ 2451155Sbostic (F)->lfs_bsize, NOCRED, &BP)) \ 2551155Sbostic panic("ifile read"); \ 2651155Sbostic (I) = (IFILE *)BP->b_un.b_addr + IN % IFPB(F); 2747571Skarels 2851155Sbostic ino_t 2951155Sbostic lfs_ialloc(fs, pip, ipp, cred) 3051155Sbostic LFS *fs; 31*51183Sbostic INODE *pip, **ipp; 32*51183Sbostic UCRED *cred; 3351155Sbostic { 34*51183Sbostic BUF *bp; 3551155Sbostic IFILE *ifp; 36*51183Sbostic INODE *ip; 37*51183Sbostic VNODE *vp; 3851155Sbostic ino_t new_ino; 3951155Sbostic int error; 404359Smckusick 4151155Sbostic new_ino = fs->lfs_free; 4251155Sbostic printf("lfs_ialloc: next free %d\n", new_ino); 4351155Sbostic if (new_ino == LFS_UNUSED_INUM) { /* XXX -- allocate more */ 4451155Sbostic uprintf("\n%s: no inodes left\n", fs->lfs_fsmnt); 4551155Sbostic log(LOG_ERR, "uid %d on %s: out of inodes\n", 4651155Sbostic cred->cr_uid, fs->lfs_fsmnt); 4751155Sbostic return (ENOSPC); 486716Smckusick } 494359Smckusick 5051155Sbostic /* Read the appropriate block from the ifile */ 5151155Sbostic vp = fs->lfs_ivnode; 5251155Sbostic LFS_IENTRY(ifp, fs, new_ino, bp); 5351155Sbostic 5451155Sbostic if (ifp->if_daddr != LFS_UNUSED_DADDR) 5551155Sbostic panic("lfs_ialloc: corrupt free list"); 5651155Sbostic 5751155Sbostic /* Remove from free list, set the access time. */ 58*51183Sbostic fs->lfs_free = ifp->if_nextfree; 5951155Sbostic ifp->if_st_atime = time.tv_sec; 6039678Smckusick brelse(bp); 614426Smckusic 6251155Sbostic error = lfs_vcreate(ITOV(pip)->v_mount, new_ino, &vp); 6351155Sbostic if (error) 6437735Smckusick return (error); 6551155Sbostic 6651155Sbostic ip = VTOI(vp); 6751155Sbostic VREF(ip->i_devvp); 6851155Sbostic 6938255Smckusick /* 7038255Smckusick * Set up a new generation number for this inode. 7138255Smckusick */ 7238255Smckusick if (++nextgennumber < (u_long)time.tv_sec) 7338255Smckusick nextgennumber = time.tv_sec; 7438255Smckusick ip->i_gen = nextgennumber; 754359Smckusick 7651155Sbostic lfs_hqueue(ip); 774359Smckusick 7851155Sbostic *ipp = ip; 7951155Sbostic return (0); 804359Smckusick } 814359Smckusick 8251155Sbostic void 8351155Sbostic lfs_ifree(ip) 84*51183Sbostic INODE *ip; 859163Ssam { 86*51183Sbostic BUF *bp; 8751155Sbostic IFILE *ifp; 8851155Sbostic LFS *fs; 8951155Sbostic ino_t ino; 904651Smckusic 9151155Sbostic printf("lfs_ifree: free %d\n", ip->i_number); 9251155Sbostic fs = ip->i_lfs; 9351155Sbostic ino = ip->i_number; 9451155Sbostic LFS_IENTRY(ifp, fs, ino, bp); 954651Smckusic 9651155Sbostic ifp->if_daddr = LFS_UNUSED_DADDR; 9751155Sbostic ++ifp->if_version; 9851155Sbostic ifp->if_nextfree = fs->lfs_free; 9951155Sbostic brelse(bp); 10051155Sbostic fs->lfs_free = ino; 10151155Sbostic fs->lfs_fmod = 1; 1024359Smckusick } 1034359Smckusick 1044359Smckusick daddr_t 10551155Sbostic itod(fs, ino) 10651155Sbostic LFS *fs; 10751155Sbostic ino_t ino; 1084426Smckusic { 109*51183Sbostic BUF *bp; 11051155Sbostic IFILE *ifp; 11151155Sbostic daddr_t iaddr; 1124426Smckusic 11351155Sbostic printf("itod: ino %d\n", ino); 11451155Sbostic LFS_IENTRY(ifp, fs, ino, bp); 1154426Smckusic 11651155Sbostic if (ifp->if_daddr == LFS_UNUSED_DADDR) 11751155Sbostic panic("itod: unused daddr"); 118*51183Sbostic iaddr = ifp->if_daddr; 119*51183Sbostic brelse(bp); 120*51183Sbostic return (iaddr); 1214463Smckusic } 1224463Smckusic 123*51183Sbostic DINODE * 12451155Sbostic lfs_ifind(fs, ino, page) 12551155Sbostic LFS *fs; 12651155Sbostic ino_t ino; 12751155Sbostic void *page; 1284463Smckusic { 129*51183Sbostic register DINODE *dip; 13051155Sbostic register int cnt; 1314463Smckusic 13251155Sbostic printf("lfs_ifind: inode %d\n", ino); 13351155Sbostic dip = page; 13451155Sbostic for (cnt = INOPB(fs); cnt--; ++dip) 13551155Sbostic if (dip->di_inum == ino) 13651155Sbostic return (dip); 13734143Smckusick 13851155Sbostic (void)printf("lfs_ifind: dinode %u not found", ino); 13951155Sbostic panic("lfs_ifind: inode not found"); 14016784Smckusick /* NOTREACHED */ 1414359Smckusick } 1424359Smckusick 1435375Smckusic /* 14451155Sbostic * Create a new vnode/inode and initialize the fields we can. 1455375Smckusic */ 14651155Sbostic lfs_vcreate(mp, ino, vpp) 147*51183Sbostic MOUNT *mp; 14851155Sbostic ino_t ino; 149*51183Sbostic VNODE **vpp; 1504359Smckusick { 151*51183Sbostic INODE *ip; 152*51183Sbostic UFSMOUNT *ump; 15351155Sbostic int error, i; 1544359Smckusick 15551155Sbostic printf("lfs_vcreate: ino %d\n", ino); 15651155Sbostic error = getnewvnode(VT_LFS, mp, &lfs_vnodeops, vpp); 15751155Sbostic if (error) 15851155Sbostic return(error); 1594359Smckusick 16051155Sbostic ump = VFSTOUFS(mp); 1614651Smckusic 16251155Sbostic /* Initialize the inode. */ 16351155Sbostic ip = VTOI(*vpp); 16451155Sbostic ip->i_diroff = 0; 16551155Sbostic ip->i_devvp = ump->um_devvp; 16651155Sbostic ip->i_dev = ump->um_dev; 16751155Sbostic ip->i_flag = 0; 16851155Sbostic ip->i_lfs = ump->um_lfs; 16951155Sbostic ip->i_lockf = 0; 17051155Sbostic ip->i_mode = 0; 171*51183Sbostic ip->i_number = ip->i_din.di_inum = ino; 17251155Sbostic ip->i_vnode = *vpp; 17351155Sbostic #ifdef QUOTA 17451155Sbostic for (i = 0; i < MAXQUOTAS; i++) 17551155Sbostic ip->i_dquot[i] = NODQUOT; 17651155Sbostic #endif 17751155Sbostic return (0); 1784651Smckusic } 179*51183Sbostic 180*51183Sbostic /* 181*51183Sbostic * Return the current version number for a specific inode. 182*51183Sbostic */ 183*51183Sbostic u_long 184*51183Sbostic lfs_getversion(fs, ino) 185*51183Sbostic LFS *fs; 186*51183Sbostic ino_t ino; 187*51183Sbostic { 188*51183Sbostic IFILE *ifp; 189*51183Sbostic BUF *bp; 190*51183Sbostic int version; 191*51183Sbostic 192*51183Sbostic printf("lfs_getversion: %d\n", ino); 193*51183Sbostic LFS_IENTRY(ifp, fs, ino, bp); 194*51183Sbostic version = ifp->if_version; 195*51183Sbostic brelse(bp); 196*51183Sbostic return(version); 197*51183Sbostic } 198