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*51347Sbostic * @(#)lfs_alloc.c 7.32 (Berkeley) 10/09/91 823394Smckusick */ 94359Smckusick 1051215Sbostic #ifdef LOGFS 1117097Sbloom #include "param.h" 1251155Sbostic #include "kernel.h" 1317097Sbloom #include "buf.h" 1437735Smckusick #include "vnode.h" 1518307Sralph #include "syslog.h" 1651215Sbostic #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 2351215Sbostic /* 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)) \ 2751215Sbostic panic("lfs_ientry: read"); \ 2851155Sbostic (I) = (IFILE *)BP->b_un.b_addr + IN % IFPB(F); 2947571Skarels 3051215Sbostic /* 3151215Sbostic * Allocate a new inode. 3251215Sbostic */ 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 4651215Sbostic /* Get the head of the freelist. */ 4751155Sbostic new_ino = fs->lfs_free; 4851215Sbostic if (new_ino == LFS_UNUSED_INUM) { 4951215Sbostic /* 5051215Sbostic * XXX 5151215Sbostic * Currently, no more inodes are allocated if the ifile fills 5251215Sbostic * up. The ifile should be extended instead. 5351215Sbostic */ 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 } 5951215Sbostic printf("lfs_ialloc: allocate inode %d\n", new_ino); 604359Smckusick 6151215Sbostic /* Read the appropriate block from the ifile. */ 6251155Sbostic LFS_IENTRY(ifp, fs, new_ino, bp); 6351155Sbostic 6451155Sbostic if (ifp->if_daddr != LFS_UNUSED_DADDR) 6551215Sbostic panic("lfs_ialloc: inuse inode on the free list"); 6651155Sbostic 6751215Sbostic /* 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; 7051215Sbostic lfs_bwrite(bp); 714426Smckusic 7251215Sbostic /* 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); 7651215Sbostic *ipp = ip = VTOI(vp); 7751155Sbostic 7851215Sbostic /* 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 8351215Sbostic /* Insert into the inode hash table. */ 8451155Sbostic lfs_hqueue(ip); 854359Smckusick 8651215Sbostic /* Set superblock modified bit and increment file count. */ 8751215Sbostic fs->lfs_fmod = 1; 8851215Sbostic ++fs->lfs_nfiles; 8951155Sbostic return (0); 904359Smckusick } 914359Smckusick 9251215Sbostic /* 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); 10351215Sbostic /* Get the inode number and file system. */ 10451155Sbostic fs = ip->i_lfs; 10551155Sbostic ino = ip->i_number; 10651215Sbostic 10751215Sbostic /* 10851215Sbostic * Read the appropriate block from the ifile. Set the inode entry to 10951215Sbostic * unused, increment its version number and link it into the free chain. 11051215Sbostic */ 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; 11651215Sbostic 11751215Sbostic lfs_bwrite(bp); 11851215Sbostic 11951215Sbostic /* Set superblock modified bit and decrement file count. */ 12051155Sbostic fs->lfs_fmod = 1; 12151215Sbostic --fs->lfs_nfiles; 1224359Smckusick } 1234359Smckusick 12451215Sbostic /* 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 13451215Sbostic /* Read the appropriate block from the ifile. */ 13551155Sbostic LFS_IENTRY(ifp, fs, ino, bp); 1364426Smckusic 13751155Sbostic if (ifp->if_daddr == LFS_UNUSED_DADDR) 13851215Sbostic panic("itod: unused disk address"); 13951183Sbostic iaddr = ifp->if_daddr; 14051183Sbostic brelse(bp); 14151183Sbostic return (iaddr); 1424463Smckusic } 1434463Smckusic 14451215Sbostic /* 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 16051215Sbostic panic("lfs_ifind: dinode %%u not found", ino); 16116784Smckusick /* NOTREACHED */ 1624359Smckusick } 1634359Smckusick 16451215Sbostic /* Create a new vnode/inode pair and initialize what fields we can. */ 165*51347Sbostic int 16651155Sbostic lfs_vcreate(mp, ino, vpp) 16751183Sbostic MOUNT *mp; 16851155Sbostic ino_t ino; 16951183Sbostic VNODE **vpp; 1704359Smckusick { 17151183Sbostic INODE *ip; 17251183Sbostic UFSMOUNT *ump; 17351155Sbostic int error, i; 1744359Smckusick 17551155Sbostic printf("lfs_vcreate: ino %d\n", ino); 17651215Sbostic /* Create the vnode. */ 17751215Sbostic if (error = getnewvnode(VT_LFS, mp, &lfs_vnodeops, vpp)) 17851311Sbostic return (error); 1794359Smckusick 18051215Sbostic /* Get a pointer to the private mount structure. */ 18151155Sbostic ump = VFSTOUFS(mp); 1824651Smckusic 18351155Sbostic /* Initialize the inode. */ 18451155Sbostic ip = VTOI(*vpp); 18551155Sbostic ip->i_diroff = 0; 18651155Sbostic ip->i_devvp = ump->um_devvp; 18751155Sbostic ip->i_dev = ump->um_dev; 18851155Sbostic ip->i_flag = 0; 18951155Sbostic ip->i_lfs = ump->um_lfs; 19051155Sbostic ip->i_lockf = 0; 19151155Sbostic ip->i_mode = 0; 19251183Sbostic ip->i_number = ip->i_din.di_inum = ino; 19351155Sbostic ip->i_vnode = *vpp; 19451155Sbostic #ifdef QUOTA 19551155Sbostic for (i = 0; i < MAXQUOTAS; i++) 19651155Sbostic ip->i_dquot[i] = NODQUOT; 19751155Sbostic #endif 19851215Sbostic VREF(ip->i_devvp); /* XXX: Why? */ 19951155Sbostic return (0); 2004651Smckusic } 20151183Sbostic 20251215Sbostic /* Return the current version number for a specific inode. */ 20351183Sbostic u_long 20451183Sbostic lfs_getversion(fs, ino) 20551183Sbostic LFS *fs; 20651183Sbostic ino_t ino; 20751183Sbostic { 20851215Sbostic BUF *bp; 20951183Sbostic IFILE *ifp; 21051215Sbostic u_long version; 21151183Sbostic 21251215Sbostic /* 21351311Sbostic * Read the appropriate block from the ifile. Return the 21451311Sbostic * version number. 21551215Sbostic */ 21651183Sbostic LFS_IENTRY(ifp, fs, ino, bp); 21751183Sbostic version = ifp->if_version; 21851183Sbostic brelse(bp); 21951311Sbostic return (version); 22051183Sbostic } 22151215Sbostic 22251215Sbostic /* Set values in the ifile for the inode. */ 22351215Sbostic void 22451215Sbostic lfs_iset(ip, daddr, atime) 22551215Sbostic INODE *ip; 22651215Sbostic daddr_t daddr; 22751215Sbostic time_t atime; 22851215Sbostic { 22951215Sbostic BUF *bp; 23051215Sbostic IFILE *ifp; 23151215Sbostic LFS *fs; 23251215Sbostic ino_t ino; 23351215Sbostic 23451311Sbostic printf("lfs_iset: setting ino %d daddr %lx time %lx\n", 23551311Sbostic ip->i_number, daddr, atime); 23651215Sbostic 23751215Sbostic fs = ip->i_lfs; 23851215Sbostic ino = ip->i_number; 23951215Sbostic LFS_IENTRY(ifp, fs, ino, bp); 24051215Sbostic 24151215Sbostic ifp->if_daddr = daddr; 24251215Sbostic ifp->if_st_atime = atime; 24351215Sbostic lfs_bwrite(bp); 24451215Sbostic } 24551215Sbostic #endif /* LOGFS */ 246