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*51215Sbostic * @(#)lfs_alloc.c 7.30 (Berkeley) 10/02/91 823394Smckusick */ 94359Smckusick 10*51215Sbostic #ifdef LOGFS 1117097Sbloom #include "param.h" 1251155Sbostic #include "kernel.h" 1317097Sbloom #include "buf.h" 1437735Smckusick #include "vnode.h" 1518307Sralph #include "syslog.h" 16*51215Sbostic #include "mount.h" 1751155Sbostic #include "../ufs/quota.h" 1851155Sbostic #include "../ufs/inode.h" 1951155Sbostic #include "../ufs/ufsmount.h" 2051155Sbostic #include "lfs.h" 2151155Sbostic #include "lfs_extern.h" 224359Smckusick 23*51215Sbostic /* Read in the block containing a specific inode from the ifile. */ 2451155Sbostic #define LFS_IENTRY(I, F, IN, BP) \ 2551155Sbostic if (bread((F)->lfs_ivnode, (IN) / IFPB(F) + (F)->lfs_segtabsz, \ 2651155Sbostic (F)->lfs_bsize, NOCRED, &BP)) \ 27*51215Sbostic panic("lfs_ientry: read"); \ 2851155Sbostic (I) = (IFILE *)BP->b_un.b_addr + IN % IFPB(F); 2947571Skarels 30*51215Sbostic /* 31*51215Sbostic * Allocate a new inode. 32*51215Sbostic */ 3351155Sbostic ino_t 3451155Sbostic lfs_ialloc(fs, pip, ipp, cred) 3551155Sbostic LFS *fs; 3651183Sbostic INODE *pip, **ipp; 3751183Sbostic UCRED *cred; 3851155Sbostic { 3951183Sbostic BUF *bp; 4051155Sbostic IFILE *ifp; 4151183Sbostic INODE *ip; 4251183Sbostic VNODE *vp; 4351155Sbostic ino_t new_ino; 4451155Sbostic int error; 454359Smckusick 46*51215Sbostic /* Get the head of the freelist. */ 4751155Sbostic new_ino = fs->lfs_free; 48*51215Sbostic if (new_ino == LFS_UNUSED_INUM) { 49*51215Sbostic /* 50*51215Sbostic * XXX 51*51215Sbostic * Currently, no more inodes are allocated if the ifile fills 52*51215Sbostic * up. The ifile should be extended instead. 53*51215Sbostic */ 5451155Sbostic uprintf("\n%s: no inodes left\n", fs->lfs_fsmnt); 5551155Sbostic log(LOG_ERR, "uid %d on %s: out of inodes\n", 5651155Sbostic cred->cr_uid, fs->lfs_fsmnt); 5751155Sbostic return (ENOSPC); 586716Smckusick } 59*51215Sbostic printf("lfs_ialloc: allocate inode %d\n", new_ino); 604359Smckusick 61*51215Sbostic /* Read the appropriate block from the ifile. */ 6251155Sbostic LFS_IENTRY(ifp, fs, new_ino, bp); 6351155Sbostic 6451155Sbostic if (ifp->if_daddr != LFS_UNUSED_DADDR) 65*51215Sbostic panic("lfs_ialloc: inuse inode on the free list"); 6651155Sbostic 67*51215Sbostic /* Remove from the free list, set the access time, write it back. */ 6851183Sbostic fs->lfs_free = ifp->if_nextfree; 6951155Sbostic ifp->if_st_atime = time.tv_sec; 70*51215Sbostic lfs_bwrite(bp); 714426Smckusic 72*51215Sbostic /* Create a vnode to associate with the inode. */ 7351155Sbostic error = lfs_vcreate(ITOV(pip)->v_mount, new_ino, &vp); 7451155Sbostic if (error) 7537735Smckusick return (error); 76*51215Sbostic *ipp = ip = VTOI(vp); 7751155Sbostic 78*51215Sbostic /* Set a new generation number for this inode. */ 7938255Smckusick if (++nextgennumber < (u_long)time.tv_sec) 8038255Smckusick nextgennumber = time.tv_sec; 8138255Smckusick ip->i_gen = nextgennumber; 824359Smckusick 83*51215Sbostic /* Insert into the inode hash table. */ 8451155Sbostic lfs_hqueue(ip); 854359Smckusick 86*51215Sbostic /* Set superblock modified bit and increment file count. */ 87*51215Sbostic fs->lfs_fmod = 1; 88*51215Sbostic ++fs->lfs_nfiles; 8951155Sbostic return (0); 904359Smckusick } 914359Smckusick 92*51215Sbostic /* Free an inode. */ 9351155Sbostic void 9451155Sbostic lfs_ifree(ip) 9551183Sbostic INODE *ip; 969163Ssam { 9751183Sbostic BUF *bp; 9851155Sbostic IFILE *ifp; 9951155Sbostic LFS *fs; 10051155Sbostic ino_t ino; 1014651Smckusic 10251155Sbostic printf("lfs_ifree: free %d\n", ip->i_number); 103*51215Sbostic /* Get the inode number and file system. */ 10451155Sbostic fs = ip->i_lfs; 10551155Sbostic ino = ip->i_number; 106*51215Sbostic 107*51215Sbostic /* 108*51215Sbostic * Read the appropriate block from the ifile. Set the inode entry to 109*51215Sbostic * unused, increment its version number and link it into the free chain. 110*51215Sbostic */ 11151155Sbostic LFS_IENTRY(ifp, fs, ino, bp); 11251155Sbostic ifp->if_daddr = LFS_UNUSED_DADDR; 11351155Sbostic ++ifp->if_version; 11451155Sbostic ifp->if_nextfree = fs->lfs_free; 11551155Sbostic fs->lfs_free = ino; 116*51215Sbostic 117*51215Sbostic lfs_bwrite(bp); 118*51215Sbostic 119*51215Sbostic /* Set superblock modified bit and decrement file count. */ 12051155Sbostic fs->lfs_fmod = 1; 121*51215Sbostic --fs->lfs_nfiles; 1224359Smckusick } 1234359Smckusick 124*51215Sbostic /* Translate an inode number to a disk address. */ 1254359Smckusick daddr_t 12651155Sbostic itod(fs, ino) 12751155Sbostic LFS *fs; 12851155Sbostic ino_t ino; 1294426Smckusic { 13051183Sbostic BUF *bp; 13151155Sbostic IFILE *ifp; 13251155Sbostic daddr_t iaddr; 1334426Smckusic 134*51215Sbostic /* Read the appropriate block from the ifile. */ 13551155Sbostic LFS_IENTRY(ifp, fs, ino, bp); 1364426Smckusic 13751155Sbostic if (ifp->if_daddr == LFS_UNUSED_DADDR) 138*51215Sbostic panic("itod: unused disk address"); 13951183Sbostic iaddr = ifp->if_daddr; 14051183Sbostic brelse(bp); 14151183Sbostic return (iaddr); 1424463Smckusic } 1434463Smckusic 144*51215Sbostic /* Search a block for a specific dinode. */ 14551183Sbostic DINODE * 14651155Sbostic lfs_ifind(fs, ino, page) 14751155Sbostic LFS *fs; 14851155Sbostic ino_t ino; 14951155Sbostic void *page; 1504463Smckusic { 15151183Sbostic register DINODE *dip; 15251155Sbostic register int cnt; 1534463Smckusic 15451155Sbostic printf("lfs_ifind: inode %d\n", ino); 15551155Sbostic dip = page; 15651155Sbostic for (cnt = INOPB(fs); cnt--; ++dip) 15751155Sbostic if (dip->di_inum == ino) 15851155Sbostic return (dip); 15934143Smckusick 160*51215Sbostic panic("lfs_ifind: dinode %%u not found", ino); 16116784Smckusick /* NOTREACHED */ 1624359Smckusick } 1634359Smckusick 164*51215Sbostic /* Create a new vnode/inode pair and initialize what fields we can. */ 16551155Sbostic lfs_vcreate(mp, ino, vpp) 16651183Sbostic MOUNT *mp; 16751155Sbostic ino_t ino; 16851183Sbostic VNODE **vpp; 1694359Smckusick { 17051183Sbostic INODE *ip; 17151183Sbostic UFSMOUNT *ump; 17251155Sbostic int error, i; 1734359Smckusick 17451155Sbostic printf("lfs_vcreate: ino %d\n", ino); 175*51215Sbostic /* Create the vnode. */ 176*51215Sbostic if (error = getnewvnode(VT_LFS, mp, &lfs_vnodeops, vpp)) 17751155Sbostic return(error); 1784359Smckusick 179*51215Sbostic /* Get a pointer to the private mount structure. */ 18051155Sbostic ump = VFSTOUFS(mp); 1814651Smckusic 18251155Sbostic /* Initialize the inode. */ 18351155Sbostic ip = VTOI(*vpp); 18451155Sbostic ip->i_diroff = 0; 18551155Sbostic ip->i_devvp = ump->um_devvp; 18651155Sbostic ip->i_dev = ump->um_dev; 18751155Sbostic ip->i_flag = 0; 18851155Sbostic ip->i_lfs = ump->um_lfs; 18951155Sbostic ip->i_lockf = 0; 19051155Sbostic ip->i_mode = 0; 19151183Sbostic ip->i_number = ip->i_din.di_inum = ino; 19251155Sbostic ip->i_vnode = *vpp; 19351155Sbostic #ifdef QUOTA 19451155Sbostic for (i = 0; i < MAXQUOTAS; i++) 19551155Sbostic ip->i_dquot[i] = NODQUOT; 19651155Sbostic #endif 197*51215Sbostic VREF(ip->i_devvp); /* XXX: Why? */ 19851155Sbostic return (0); 1994651Smckusic } 20051183Sbostic 201*51215Sbostic /* Return the current version number for a specific inode. */ 20251183Sbostic u_long 20351183Sbostic lfs_getversion(fs, ino) 20451183Sbostic LFS *fs; 20551183Sbostic ino_t ino; 20651183Sbostic { 207*51215Sbostic BUF *bp; 20851183Sbostic IFILE *ifp; 209*51215Sbostic u_long version; 21051183Sbostic 211*51215Sbostic /* 212*51215Sbostic * Read the appropriate block from the ifile. Return the version 213*51215Sbostic * number. 214*51215Sbostic */ 21551183Sbostic LFS_IENTRY(ifp, fs, ino, bp); 21651183Sbostic version = ifp->if_version; 21751183Sbostic brelse(bp); 21851183Sbostic return(version); 21951183Sbostic } 220*51215Sbostic 221*51215Sbostic /* Set values in the ifile for the inode. */ 222*51215Sbostic void 223*51215Sbostic lfs_iset(ip, daddr, atime) 224*51215Sbostic INODE *ip; 225*51215Sbostic daddr_t daddr; 226*51215Sbostic time_t atime; 227*51215Sbostic { 228*51215Sbostic BUF *bp; 229*51215Sbostic IFILE *ifp; 230*51215Sbostic LFS *fs; 231*51215Sbostic ino_t ino; 232*51215Sbostic 233*51215Sbostic printf("lfs_iset: setting ino %d daddr %lx time %lx\n", ip->i_number, daddr, atime); 234*51215Sbostic 235*51215Sbostic fs = ip->i_lfs; 236*51215Sbostic ino = ip->i_number; 237*51215Sbostic LFS_IENTRY(ifp, fs, ino, bp); 238*51215Sbostic 239*51215Sbostic ifp->if_daddr = daddr; 240*51215Sbostic ifp->if_st_atime = atime; 241*51215Sbostic lfs_bwrite(bp); 242*51215Sbostic } 243*51215Sbostic #endif /* LOGFS */ 244