1 /* 2 * Copyright (c) 1982, 1986, 1989 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)lfs_alloc.c 7.28 (Berkeley) 09/20/91 8 */ 9 10 #include "param.h" 11 #include "kernel.h" 12 #include "buf.h" 13 #include "vnode.h" 14 #include "syslog.h" 15 #include "../ufs/quota.h" 16 #include "../ufs/inode.h" 17 #include "mount.h" 18 #include "../ufs/ufsmount.h" 19 #include "lfs.h" 20 #include "lfs_extern.h" 21 22 #define LFS_IENTRY(I, F, IN, BP) \ 23 if (bread((F)->lfs_ivnode, (IN) / IFPB(F) + (F)->lfs_segtabsz, \ 24 (F)->lfs_bsize, NOCRED, &BP)) \ 25 panic("ifile read"); \ 26 (I) = (IFILE *)BP->b_un.b_addr + IN % IFPB(F); 27 28 ino_t 29 lfs_ialloc(fs, pip, ipp, cred) 30 LFS *fs; 31 struct inode *pip, **ipp; 32 struct ucred *cred; 33 { 34 IFILE *ifp; 35 struct buf *bp; 36 struct inode *ip; 37 struct vnode *vp; 38 ino_t new_ino; 39 int error; 40 41 new_ino = fs->lfs_free; 42 printf("lfs_ialloc: next free %d\n", new_ino); 43 if (new_ino == LFS_UNUSED_INUM) { /* XXX -- allocate more */ 44 uprintf("\n%s: no inodes left\n", fs->lfs_fsmnt); 45 log(LOG_ERR, "uid %d on %s: out of inodes\n", 46 cred->cr_uid, fs->lfs_fsmnt); 47 return (ENOSPC); 48 } 49 50 /* Read the appropriate block from the ifile */ 51 vp = fs->lfs_ivnode; 52 LFS_IENTRY(ifp, fs, new_ino, bp); 53 54 if (ifp->if_daddr != LFS_UNUSED_DADDR) 55 panic("lfs_ialloc: corrupt free list"); 56 57 /* Remove from free list, set the access time. */ 58 ifp->if_st_atime = time.tv_sec; 59 fs->lfs_free = ifp->if_nextfree; 60 brelse(bp); 61 62 error = lfs_vcreate(ITOV(pip)->v_mount, new_ino, &vp); 63 if (error) 64 return (error); 65 66 ip = VTOI(vp); 67 VREF(ip->i_devvp); 68 69 /* 70 * Set up a new generation number for this inode. 71 */ 72 if (++nextgennumber < (u_long)time.tv_sec) 73 nextgennumber = time.tv_sec; 74 ip->i_gen = nextgennumber; 75 76 lfs_hqueue(ip); 77 78 *ipp = ip; 79 return (0); 80 } 81 82 void 83 lfs_ifree(ip) 84 struct inode *ip; 85 { 86 IFILE *ifp; 87 LFS *fs; 88 struct buf *bp; 89 ino_t ino; 90 91 printf("lfs_ifree: free %d\n", ip->i_number); 92 fs = ip->i_lfs; 93 ino = ip->i_number; 94 LFS_IENTRY(ifp, fs, ino, bp); 95 96 ifp->if_daddr = LFS_UNUSED_DADDR; 97 ++ifp->if_version; 98 ifp->if_nextfree = fs->lfs_free; 99 brelse(bp); 100 fs->lfs_free = ino; 101 fs->lfs_fmod = 1; 102 } 103 104 daddr_t 105 itod(fs, ino) 106 LFS *fs; 107 ino_t ino; 108 { 109 struct buf *bp; 110 IFILE *ifp; 111 daddr_t iaddr; 112 113 printf("itod: ino %d\n", ino); 114 LFS_IENTRY(ifp, fs, ino, bp); 115 116 if (ifp->if_daddr == LFS_UNUSED_DADDR) 117 panic("itod: unused daddr"); 118 printf("itod: about to return %lx\n", ifp->if_daddr); 119 return (ifp->if_daddr); 120 } 121 122 struct dinode * 123 lfs_ifind(fs, ino, page) 124 LFS *fs; 125 ino_t ino; 126 void *page; 127 { 128 register struct dinode *dip; 129 register int cnt; 130 131 printf("lfs_ifind: inode %d\n", ino); 132 dip = page; 133 for (cnt = INOPB(fs); cnt--; ++dip) 134 if (dip->di_inum == ino) 135 return (dip); 136 137 (void)printf("lfs_ifind: dinode %u not found", ino); 138 panic("lfs_ifind: inode not found"); 139 /* NOTREACHED */ 140 } 141 142 /* 143 * Create a new vnode/inode and initialize the fields we can. 144 */ 145 lfs_vcreate(mp, ino, vpp) 146 struct mount *mp; 147 ino_t ino; 148 struct vnode **vpp; 149 { 150 struct inode *ip; 151 struct ufsmount *ump; 152 int error, i; 153 154 printf("lfs_vcreate: ino %d\n", ino); 155 error = getnewvnode(VT_LFS, mp, &lfs_vnodeops, vpp); 156 if (error) 157 return(error); 158 159 ump = VFSTOUFS(mp); 160 161 /* Initialize the inode. */ 162 ip = VTOI(*vpp); 163 ip->i_diroff = 0; 164 ip->i_devvp = ump->um_devvp; 165 ip->i_dev = ump->um_dev; 166 ip->i_flag = 0; 167 ip->i_lfs = ump->um_lfs; 168 ip->i_lockf = 0; 169 ip->i_mode = 0; 170 ip->i_number = ino; 171 ip->i_vnode = *vpp; 172 #ifdef QUOTA 173 for (i = 0; i < MAXQUOTAS; i++) 174 ip->i_dquot[i] = NODQUOT; 175 #endif 176 return (0); 177 } 178