1 /* 2 * Copyright (c) 1991 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)lfs_alloc.c 7.38 (Berkeley) 12/16/91 8 */ 9 10 #include <sys/param.h> 11 #include <sys/kernel.h> 12 #include <sys/buf.h> 13 #include <sys/vnode.h> 14 #include <sys/syslog.h> 15 #include <sys/mount.h> 16 #include <sys/malloc.h> 17 18 #include <ufs/ufs/quota.h> 19 #include <ufs/ufs/inode.h> 20 #include <ufs/ufs/ufsmount.h> 21 22 #include <ufs/lfs/lfs.h> 23 #include <ufs/lfs/lfs_extern.h> 24 25 extern u_long nextgennumber; 26 27 /* Allocate a new inode. */ 28 /* ARGSUSED */ 29 int 30 lfs_valloc(pvp, notused, cred, vpp) 31 VNODE *pvp, **vpp; 32 int notused; 33 UCRED *cred; 34 { 35 struct lfs *fs; 36 BUF *bp; 37 IFILE *ifp; 38 INODE *ip; 39 VNODE *vp; 40 ino_t new_ino; 41 int error; 42 43 #ifdef VERBOSE 44 printf("lfs_valloc\n"); 45 #endif 46 /* Get the head of the freelist. */ 47 fs = VTOI(pvp)->i_lfs; 48 new_ino = fs->lfs_free; 49 if (new_ino == LFS_UNUSED_INUM) { 50 /* 51 * XXX 52 * Currently, no more inodes are allocated if the ifile fills 53 * up. The ifile should be extended instead. 54 */ 55 uprintf("\n%s: no inodes left\n", fs->lfs_fsmnt); 56 log(LOG_ERR, "uid %d on %s: out of inodes\n", 57 cred->cr_uid, fs->lfs_fsmnt); 58 return (ENOSPC); 59 } 60 #ifdef ALLOCPRINT 61 printf("lfs_ialloc: allocate inode %d\n", new_ino); 62 #endif 63 64 /* 65 * Remove the inode from the free list and write the free list 66 * back. 67 */ 68 LFS_IENTRY(ifp, fs, new_ino, bp); 69 if (ifp->if_daddr != LFS_UNUSED_DADDR) 70 panic("lfs_ialloc: inuse inode on the free list"); 71 fs->lfs_free = ifp->if_nextfree; 72 ifp->if_st_atime = time.tv_sec; 73 LFS_IWRITE(fs, bp); 74 75 /* Create a vnode to associate with the inode. */ 76 if (error = lfs_vcreate(pvp->v_mount, new_ino, &vp)) 77 return (error); 78 *vpp = vp; 79 ip = VTOI(vp); 80 VREF(ip->i_devvp); 81 82 /* Set a new generation number for this inode. */ 83 if (++nextgennumber < (u_long)time.tv_sec) 84 nextgennumber = time.tv_sec; 85 ip->i_gen = nextgennumber; 86 87 /* Insert into the inode hash table. */ 88 ufs_ihashins(ip); 89 90 /* Set superblock modified bit and increment file count. */ 91 fs->lfs_fmod = 1; 92 ++fs->lfs_nfiles; 93 return (0); 94 } 95 96 /* Create a new vnode/inode pair and initialize what fields we can. */ 97 int 98 lfs_vcreate(mp, ino, vpp) 99 MOUNT *mp; 100 ino_t ino; 101 VNODE **vpp; 102 { 103 extern struct vnodeops lfs_vnodeops; 104 INODE *ip; 105 UFSMOUNT *ump; 106 int error, i; 107 108 #ifdef VERBOSE 109 printf("lfs_vcreate: ino %d\n", ino); 110 #endif 111 /* Create the vnode. */ 112 if (error = getnewvnode(VT_LFS, mp, &lfs_vnodeops, vpp)) { 113 *vpp = NULL; 114 return (error); 115 } 116 117 /* Get a pointer to the private mount structure. */ 118 ump = VFSTOUFS(mp); 119 120 /* Initialize the inode. */ 121 MALLOC(ip, struct inode *, sizeof(struct inode), M_LFSNODE, M_WAITOK); 122 (*vpp)->v_data = ip; 123 ip->i_vnode = *vpp; 124 ip->i_flag = 0; 125 ip->i_mode = 0; 126 ip->i_diroff = 0; 127 ip->i_lockf = 0; 128 ip->i_dev = ump->um_dev; 129 ip->i_number = ip->i_din.di_inum = ino; 130 ip->i_lfs = ump->um_lfs; 131 ip->i_devvp = ump->um_devvp; 132 #ifdef QUOTA 133 for (i = 0; i < MAXQUOTAS; i++) 134 ip->i_dquot[i] = NODQUOT; 135 #endif 136 return (0); 137 } 138 139 /* Free an inode. */ 140 /* ARGUSED */ 141 void 142 lfs_vfree(vp, notused1, notused2) 143 VNODE *vp; 144 ino_t notused1; 145 int notused2; 146 { 147 BUF *bp; 148 IFILE *ifp; 149 INODE *ip; 150 struct lfs *fs; 151 ino_t ino; 152 153 ip = VTOI(vp); 154 #ifdef VERBOSE 155 printf("lfs_vfree: free %d\n", ip->i_number); 156 #endif 157 /* Get the inode number and file system. */ 158 fs = ip->i_lfs; 159 ino = ip->i_number; 160 161 /* 162 * Set the ifile's inode entry to unused, increment its version number 163 * and link it into the free chain. 164 */ 165 LFS_IENTRY(ifp, fs, ino, bp); 166 ifp->if_daddr = LFS_UNUSED_DADDR; 167 ++ifp->if_version; 168 ifp->if_nextfree = fs->lfs_free; 169 fs->lfs_free = ino; 170 LFS_IWRITE(fs, bp); 171 172 /* Set superblock modified bit and decrement file count. */ 173 fs->lfs_fmod = 1; 174 --fs->lfs_nfiles; 175 } 176