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*51485Sbostic * @(#)lfs_alloc.c 7.33 (Berkeley) 11/01/91 823394Smckusick */ 94359Smckusick 10*51485Sbostic #include <sys/param.h> 11*51485Sbostic #include <sys/kernel.h> 12*51485Sbostic #include <sys/buf.h> 13*51485Sbostic #include <sys/vnode.h> 14*51485Sbostic #include <sys/syslog.h> 15*51485Sbostic #include <sys/mount.h> 164359Smckusick 17*51485Sbostic #include <ufs/quota.h> 18*51485Sbostic #include <ufs/inode.h> 19*51485Sbostic #include <ufs/ufsmount.h> 2047571Skarels 21*51485Sbostic #include <lfs/lfs.h> 22*51485Sbostic #include <lfs/lfs_extern.h> 23*51485Sbostic 24*51485Sbostic /* Allocate a new inode. */ 25*51485Sbostic /* ARGSUSED */ 26*51485Sbostic int 27*51485Sbostic lfs_ialloc(pip, notused, cred, ipp) 2851183Sbostic INODE *pip, **ipp; 29*51485Sbostic int notused; 3051183Sbostic UCRED *cred; 3151155Sbostic { 32*51485Sbostic LFS *fs; 3351183Sbostic BUF *bp; 3451155Sbostic IFILE *ifp; 3551183Sbostic INODE *ip; 3651183Sbostic VNODE *vp; 3751155Sbostic ino_t new_ino; 3851155Sbostic int error; 394359Smckusick 4051215Sbostic /* Get the head of the freelist. */ 41*51485Sbostic fs = pip->i_lfs; 4251155Sbostic new_ino = fs->lfs_free; 4351215Sbostic if (new_ino == LFS_UNUSED_INUM) { 4451215Sbostic /* 4551215Sbostic * XXX 4651215Sbostic * Currently, no more inodes are allocated if the ifile fills 4751215Sbostic * up. The ifile should be extended instead. 4851215Sbostic */ 4951155Sbostic uprintf("\n%s: no inodes left\n", fs->lfs_fsmnt); 5051155Sbostic log(LOG_ERR, "uid %d on %s: out of inodes\n", 5151155Sbostic cred->cr_uid, fs->lfs_fsmnt); 5251155Sbostic return (ENOSPC); 536716Smckusick } 54*51485Sbostic #ifdef ALLOCPRINT 55*51485Sbostic printf("lfs_ialloc: allocate inode %d\n", new_ino); 56*51485Sbostic #endif 574359Smckusick 5851215Sbostic /* Read the appropriate block from the ifile. */ 5951155Sbostic LFS_IENTRY(ifp, fs, new_ino, bp); 6051155Sbostic 6151155Sbostic if (ifp->if_daddr != LFS_UNUSED_DADDR) 6251215Sbostic panic("lfs_ialloc: inuse inode on the free list"); 6351155Sbostic 6451215Sbostic /* Remove from the free list, set the access time, write it back. */ 6551183Sbostic fs->lfs_free = ifp->if_nextfree; 6651155Sbostic ifp->if_st_atime = time.tv_sec; 6751215Sbostic lfs_bwrite(bp); 684426Smckusic 6951215Sbostic /* Create a vnode to associate with the inode. */ 7051155Sbostic error = lfs_vcreate(ITOV(pip)->v_mount, new_ino, &vp); 7151155Sbostic if (error) 7237735Smckusick return (error); 7351215Sbostic *ipp = ip = VTOI(vp); 7451155Sbostic 7551215Sbostic /* Set a new generation number for this inode. */ 7638255Smckusick if (++nextgennumber < (u_long)time.tv_sec) 7738255Smckusick nextgennumber = time.tv_sec; 7838255Smckusick ip->i_gen = nextgennumber; 794359Smckusick 8051215Sbostic /* Insert into the inode hash table. */ 81*51485Sbostic ufs_ihashins(ip); 824359Smckusick 8351215Sbostic /* Set superblock modified bit and increment file count. */ 8451215Sbostic fs->lfs_fmod = 1; 8551215Sbostic ++fs->lfs_nfiles; 8651155Sbostic return (0); 874359Smckusick } 884359Smckusick 8951215Sbostic /* Create a new vnode/inode pair and initialize what fields we can. */ 9051347Sbostic int 9151155Sbostic lfs_vcreate(mp, ino, vpp) 9251183Sbostic MOUNT *mp; 9351155Sbostic ino_t ino; 9451183Sbostic VNODE **vpp; 954359Smckusick { 9651183Sbostic INODE *ip; 9751183Sbostic UFSMOUNT *ump; 9851155Sbostic int error, i; 994359Smckusick 100*51485Sbostic #ifdef ALLOCPRINT 101*51485Sbostic printf("lfs_vcreate: ino %d\n", ino); 102*51485Sbostic #endif 10351215Sbostic /* Create the vnode. */ 10451215Sbostic if (error = getnewvnode(VT_LFS, mp, &lfs_vnodeops, vpp)) 10551311Sbostic return (error); 1064359Smckusick 10751215Sbostic /* Get a pointer to the private mount structure. */ 10851155Sbostic ump = VFSTOUFS(mp); 1094651Smckusic 11051155Sbostic /* Initialize the inode. */ 11151155Sbostic ip = VTOI(*vpp); 11251155Sbostic ip->i_diroff = 0; 11351155Sbostic ip->i_devvp = ump->um_devvp; 11451155Sbostic ip->i_dev = ump->um_dev; 11551155Sbostic ip->i_flag = 0; 11651155Sbostic ip->i_lfs = ump->um_lfs; 11751155Sbostic ip->i_lockf = 0; 11851155Sbostic ip->i_mode = 0; 11951183Sbostic ip->i_number = ip->i_din.di_inum = ino; 12051155Sbostic ip->i_vnode = *vpp; 12151155Sbostic #ifdef QUOTA 12251155Sbostic for (i = 0; i < MAXQUOTAS; i++) 12351155Sbostic ip->i_dquot[i] = NODQUOT; 12451155Sbostic #endif 12551215Sbostic VREF(ip->i_devvp); /* XXX: Why? */ 12651155Sbostic return (0); 1274651Smckusic } 12851183Sbostic 129*51485Sbostic /* Free an inode. */ 130*51485Sbostic /* ARGUSED */ 13151215Sbostic void 132*51485Sbostic lfs_ifree(ip, notused1, notused2) 13351215Sbostic INODE *ip; 134*51485Sbostic ino_t notused1; 135*51485Sbostic int notused2; 13651215Sbostic { 13751215Sbostic BUF *bp; 13851215Sbostic IFILE *ifp; 13951215Sbostic LFS *fs; 14051215Sbostic ino_t ino; 14151215Sbostic 142*51485Sbostic #ifdef ALLOCPRINT 143*51485Sbostic printf("lfs_ifree: free %d\n", ip->i_number); 144*51485Sbostic #endif 145*51485Sbostic /* Get the inode number and file system. */ 14651215Sbostic fs = ip->i_lfs; 14751215Sbostic ino = ip->i_number; 148*51485Sbostic 149*51485Sbostic /* 150*51485Sbostic * Read the appropriate block from the ifile. Set the inode entry to 151*51485Sbostic * unused, increment its version number and link it into the free chain. 152*51485Sbostic */ 15351215Sbostic LFS_IENTRY(ifp, fs, ino, bp); 154*51485Sbostic ifp->if_daddr = LFS_UNUSED_DADDR; 155*51485Sbostic ++ifp->if_version; 156*51485Sbostic ifp->if_nextfree = fs->lfs_free; 157*51485Sbostic fs->lfs_free = ino; 15851215Sbostic 15951215Sbostic lfs_bwrite(bp); 160*51485Sbostic 161*51485Sbostic /* Set superblock modified bit and decrement file count. */ 162*51485Sbostic fs->lfs_fmod = 1; 163*51485Sbostic --fs->lfs_nfiles; 16451215Sbostic } 165