1/* 2 * linux/fs/sysv/ialloc.c 3 * 4 * minix/bitmap.c 5 * Copyright (C) 1991, 1992 Linus Torvalds 6 * 7 * ext/freelists.c 8 * Copyright (C) 1992 Remy Card (card@masi.ibp.fr) 9 * 10 * xenix/alloc.c 11 * Copyright (C) 1992 Doug Evans 12 * 13 * coh/alloc.c 14 * Copyright (C) 1993 Pascal Haible, Bruno Haible 15 * 16 * sysv/ialloc.c 17 * Copyright (C) 1993 Bruno Haible 18 * 19 * This file contains code for allocating/freeing inodes. 20 */ 21 22#include <linux/kernel.h> 23#include <linux/fs.h> 24#include <linux/sysv_fs.h> 25#include <linux/stddef.h> 26#include <linux/stat.h> 27#include <linux/string.h> 28#include <linux/locks.h> 29 30/* We don't trust the value of 31 sb->sv_sbd2->s_tinode = *sb->sv_sb_total_free_inodes 32 but we nevertheless keep it up to date. */ 33 34/* An inode on disk is considered free if both i_mode == 0 and i_nlink == 0. */ 35 36/* return &sb->sv_sb_fic_inodes[i] = &sbd->s_inode[i]; */ 37static inline sysv_ino_t * 38sv_sb_fic_inode(struct super_block * sb, unsigned int i) 39{ 40 if (sb->sv_bh1 == sb->sv_bh2) 41 return &sb->sv_sb_fic_inodes[i]; 42 else { 43 /* 512 byte Xenix FS */ 44 unsigned int offset = offsetof(struct xenix_super_block, s_inode[i]); 45 if (offset < 512) 46 return (sysv_ino_t*)(sb->sv_sbd1 + offset); 47 else 48 return (sysv_ino_t*)(sb->sv_sbd2 + offset); 49 } 50} 51 52struct sysv_inode * 53sysv_raw_inode(struct super_block *sb, unsigned ino, struct buffer_head **bh) 54{ 55 struct sysv_inode *res; 56 int block = sb->sv_firstinodezone + sb->sv_block_base; 57 block += (ino-1) >> sb->sv_inodes_per_block_bits; 58 *bh = sb_bread(sb, block); 59 if (!*bh) 60 return NULL; 61 res = (struct sysv_inode *) (*bh)->b_data; 62 return res + ((ino-1) & sb->sv_inodes_per_block_1); 63} 64 65static int refill_free_cache(struct super_block *sb) 66{ 67 struct buffer_head * bh; 68 struct sysv_inode * raw_inode; 69 int i = 0, ino; 70 71 ino = SYSV_ROOT_INO+1; 72 raw_inode = sysv_raw_inode(sb, ino, &bh); 73 if (!raw_inode) 74 goto out; 75 while (ino <= sb->sv_ninodes) { 76 if (raw_inode->i_mode == 0 && raw_inode->i_nlink == 0) { 77 *sv_sb_fic_inode(sb,i++) = cpu_to_fs16(sb, ino); 78 if (i == sb->sv_fic_size) 79 break; 80 } 81 if ((ino++ & sb->sv_inodes_per_block_1) == 0) { 82 brelse(bh); 83 raw_inode = sysv_raw_inode(sb, ino, &bh); 84 if (!raw_inode) 85 goto out; 86 } else 87 raw_inode++; 88 } 89 brelse(bh); 90out: 91 return i; 92} 93 94void sysv_free_inode(struct inode * inode) 95{ 96 struct super_block * sb; 97 unsigned int ino; 98 struct buffer_head * bh; 99 struct sysv_inode * raw_inode; 100 unsigned count; 101 102 sb = inode->i_sb; 103 ino = inode->i_ino; 104 if (ino <= SYSV_ROOT_INO || ino > sb->sv_ninodes) { 105 printk("sysv_free_inode: inode 0,1,2 or nonexistent inode\n"); 106 return; 107 } 108 raw_inode = sysv_raw_inode(sb, ino, &bh); 109 clear_inode(inode); 110 if (!raw_inode) { 111 printk("sysv_free_inode: unable to read inode block on device " 112 "%s\n", bdevname(inode->i_dev)); 113 return; 114 } 115 lock_super(sb); 116 count = fs16_to_cpu(sb, *sb->sv_sb_fic_count); 117 if (count < sb->sv_fic_size) { 118 *sv_sb_fic_inode(sb,count++) = cpu_to_fs16(sb, ino); 119 *sb->sv_sb_fic_count = cpu_to_fs16(sb, count); 120 } 121 fs16_add(sb, sb->sv_sb_total_free_inodes, 1); 122 dirty_sb(sb); 123 memset(raw_inode, 0, sizeof(struct sysv_inode)); 124 mark_buffer_dirty(bh); 125 unlock_super(sb); 126 brelse(bh); 127} 128 129struct inode * sysv_new_inode(const struct inode * dir, mode_t mode) 130{ 131 struct inode * inode; 132 struct super_block * sb; 133 u16 ino; 134 unsigned count; 135 136 sb = dir->i_sb; 137 inode = new_inode(sb); 138 if (!inode) 139 return ERR_PTR(-ENOMEM); 140 141 lock_super(sb); 142 count = fs16_to_cpu(sb, *sb->sv_sb_fic_count); 143 if (count == 0 || (*sv_sb_fic_inode(sb,count-1) == 0)) { 144 count = refill_free_cache(sb); 145 if (count == 0) { 146 iput(inode); 147 unlock_super(sb); 148 return ERR_PTR(-ENOSPC); 149 } 150 } 151 /* Now count > 0. */ 152 ino = *sv_sb_fic_inode(sb,--count); 153 *sb->sv_sb_fic_count = cpu_to_fs16(sb, count); 154 fs16_add(sb, sb->sv_sb_total_free_inodes, -1); 155 dirty_sb(sb); 156 157 if (dir->i_mode & S_ISGID) { 158 inode->i_gid = dir->i_gid; 159 if (S_ISDIR(mode)) 160 mode |= S_ISGID; 161 } else 162 inode->i_gid = current->fsgid; 163 164 inode->i_uid = current->fsuid; 165 inode->i_ino = fs16_to_cpu(sb, ino); 166 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; 167 inode->i_blocks = inode->i_blksize = 0; 168 inode->u.sysv_i.i_dir_start_lookup = 0; 169 insert_inode_hash(inode); 170 mark_inode_dirty(inode); 171 172 inode->i_mode = mode; /* for sysv_write_inode() */ 173 sysv_write_inode(inode, 0); /* ensure inode not allocated again */ 174 mark_inode_dirty(inode); /* cleared by sysv_write_inode() */ 175 /* That's it. */ 176 unlock_super(sb); 177 return inode; 178} 179 180unsigned long sysv_count_free_inodes(struct super_block * sb) 181{ 182 struct buffer_head * bh; 183 struct sysv_inode * raw_inode; 184 int ino, count, sb_count; 185 186 lock_super(sb); 187 188 sb_count = fs16_to_cpu(sb, *sb->sv_sb_total_free_inodes); 189 190 if (0) 191 goto trust_sb; 192 193 /* this causes a lot of disk traffic ... */ 194 count = 0; 195 ino = SYSV_ROOT_INO+1; 196 raw_inode = sysv_raw_inode(sb, ino, &bh); 197 if (!raw_inode) 198 goto Eio; 199 while (ino <= sb->sv_ninodes) { 200 if (raw_inode->i_mode == 0 && raw_inode->i_nlink == 0) 201 count++; 202 if ((ino++ & sb->sv_inodes_per_block_1) == 0) { 203 brelse(bh); 204 raw_inode = sysv_raw_inode(sb, ino, &bh); 205 if (!raw_inode) 206 goto Eio; 207 } else 208 raw_inode++; 209 } 210 brelse(bh); 211 if (count != sb_count) 212 goto Einval; 213out: 214 unlock_super(sb); 215 return count; 216 217Einval: 218 printk("sysv_count_free_inodes: " 219 "free inode count was %d, correcting to %d\n", 220 sb_count, count); 221 if (!(sb->s_flags & MS_RDONLY)) { 222 *sb->sv_sb_total_free_inodes = cpu_to_fs16(sb, count); 223 dirty_sb(sb); 224 } 225 goto out; 226 227Eio: 228 printk("sysv_count_free_inodes: unable to read inode table\n"); 229trust_sb: 230 count = sb_count; 231 goto out; 232} 233