|
|
1.1 ! root 1: /* ! 2: * linux/fs/ext/inode.c ! 3: * ! 4: * (C) 1992 Remy Card ([email protected]) ! 5: * ! 6: * from ! 7: * ! 8: * linux/fs/minix/inode.c ! 9: * ! 10: * (C) 1991 Linus Torvalds ! 11: */ ! 12: ! 13: #include <linux/string.h> ! 14: #include <linux/stat.h> ! 15: #include <linux/sched.h> ! 16: #include <linux/ext_fs.h> ! 17: #include <linux/kernel.h> ! 18: #include <linux/mm.h> ! 19: #include <asm/system.h> ! 20: #include <asm/segment.h> ! 21: ! 22: int sync_dev(int dev); ! 23: ! 24: void ext_put_inode(struct inode *inode) ! 25: { ! 26: inode->i_size = 0; ! 27: ext_truncate(inode); ! 28: ext_free_inode(inode); ! 29: } ! 30: ! 31: void ext_put_super(struct super_block *sb) ! 32: { ! 33: #ifdef EXTFS_BITMAP ! 34: int i; ! 35: #endif ! 36: ! 37: lock_super(sb); ! 38: sb->s_dev = 0; ! 39: #ifdef EXTFS_BITMAP ! 40: for(i = 0 ; i < EXT_I_MAP_SLOTS ; i++) ! 41: brelse(sb->s_imap[i]); ! 42: for(i = 0 ; i < EXT_Z_MAP_SLOTS ; i++) ! 43: brelse(sb->s_zmap[i]); ! 44: #endif ! 45: #ifdef EXTFS_FREELIST ! 46: if (sb->s_imap[1]) ! 47: brelse (sb->s_imap[1]); ! 48: if (sb->s_zmap[1]) ! 49: brelse (sb->s_zmap[1]); ! 50: #endif ! 51: free_super(sb); ! 52: return; ! 53: } ! 54: ! 55: static struct super_operations ext_sops = { ! 56: ext_read_inode, ! 57: ext_write_inode, ! 58: ext_put_inode, ! 59: ext_put_super, ! 60: ext_write_super, ! 61: ext_statfs ! 62: }; ! 63: ! 64: struct super_block *ext_read_super(struct super_block *s,void *data) ! 65: { ! 66: struct buffer_head *bh; ! 67: struct ext_super_block *es; ! 68: int dev=s->s_dev,block; ! 69: #ifdef EXTFS_BITMAP ! 70: int i; ! 71: #endif ! 72: ! 73: lock_super(s); ! 74: if (!(bh = bread(dev,1))) { ! 75: s->s_dev=0; ! 76: free_super(s); ! 77: printk("bread failed\n"); ! 78: return NULL; ! 79: } ! 80: /* *((struct ext_super_block *) s) = ! 81: *((struct ext_super_block *) bh->b_data); */ ! 82: es = (struct ext_super_block *) bh->b_data; ! 83: s->s_ninodes = es->s_ninodes; ! 84: s->s_nzones = es->s_nzones; ! 85: #ifdef EXTFS_BITMAP ! 86: s->s_imap_blocks = es->s_imap_blocks; ! 87: s->s_zmap_blocks = es->s_zmap_blocks; ! 88: #endif ! 89: s->s_firstdatazone = es->s_firstdatazone; ! 90: s->s_log_zone_size = es->s_log_zone_size; ! 91: s->s_max_size = es->s_max_size; ! 92: s->s_magic = es->s_magic; ! 93: #ifdef EXTFS_FREELIST ! 94: s->s_zmap[0] = (struct buffer_head *) es->s_firstfreeblock; ! 95: s->s_zmap[2] = (struct buffer_head *) es->s_freeblockscount; ! 96: s->s_imap[0] = (struct buffer_head *) es->s_firstfreeinode; ! 97: s->s_imap[2] = (struct buffer_head *) es->s_freeinodescount; ! 98: #endif ! 99: brelse(bh); ! 100: if (s->s_magic != EXT_SUPER_MAGIC) { ! 101: s->s_dev = 0; ! 102: free_super(s); ! 103: printk("magic match failed\n"); ! 104: return NULL; ! 105: } ! 106: #ifdef EXTFS_BITMAP ! 107: for (i=0;i < EXT_I_MAP_SLOTS;i++) ! 108: s->s_imap[i] = NULL; ! 109: for (i=0;i < EXT_Z_MAP_SLOTS;i++) ! 110: s->s_zmap[i] = NULL; ! 111: block=2; ! 112: for (i=0 ; i < s->s_imap_blocks ; i++) ! 113: if (s->s_imap[i]=bread(dev,block)) ! 114: block++; ! 115: else ! 116: break; ! 117: for (i=0 ; i < s->s_zmap_blocks ; i++) ! 118: if (s->s_zmap[i]=bread(dev,block)) ! 119: block++; ! 120: else ! 121: break; ! 122: if (block != 2+s->s_imap_blocks+s->s_zmap_blocks) { ! 123: for(i=0;i<EXT_I_MAP_SLOTS;i++) ! 124: brelse(s->s_imap[i]); ! 125: for(i=0;i<EXT_Z_MAP_SLOTS;i++) ! 126: brelse(s->s_zmap[i]); ! 127: s->s_dev=0; ! 128: free_super(s); ! 129: printk("block failed\n"); ! 130: return NULL; ! 131: } ! 132: s->s_imap[0]->b_data[0] |= 1; ! 133: s->s_zmap[0]->b_data[0] |= 1; ! 134: #endif ! 135: #ifdef EXTFS_FREELIST ! 136: if (!s->s_zmap[0]) ! 137: s->s_zmap[1] = NULL; ! 138: else ! 139: if (!(s->s_zmap[1] = bread (dev, (unsigned long) s->s_zmap[0]))) { ! 140: printk ("ext_read_super: unable to read first free block\n"); ! 141: s->s_dev = 0; ! 142: free_super(s); ! 143: return NULL; ! 144: } ! 145: if (!s->s_imap[0]) ! 146: s->s_imap[1] = NULL; ! 147: else { ! 148: block = 2 + (((unsigned long) s->s_imap[0]) - 1) / EXT_INODES_PER_BLOCK; ! 149: if (!(s->s_imap[1] = bread (dev, block))) { ! 150: printk ("ext_read_super: unable to read first free inode block\n"); ! 151: brelse(s->s_zmap[1]); ! 152: s->s_dev = 0; ! 153: free_super (s); ! 154: return NULL; ! 155: } ! 156: } ! 157: #endif ! 158: ! 159: free_super(s); ! 160: /* set up enough so that it can read an inode */ ! 161: s->s_dev = dev; ! 162: s->s_op = &ext_sops; ! 163: if (!(s->s_mounted = iget(dev,EXT_ROOT_INO))) { ! 164: s->s_dev=0; ! 165: printk("get root inode failed\n"); ! 166: return NULL; ! 167: } ! 168: return s; ! 169: } ! 170: ! 171: void ext_write_super (struct super_block *sb) ! 172: { ! 173: #ifdef EXTFS_FREELIST ! 174: struct buffer_head * bh; ! 175: struct ext_super_block * es; ! 176: ! 177: #ifdef EXTFS_DEBUG ! 178: printk ("ext_write_super called\n"); ! 179: #endif ! 180: if (!(bh = bread (sb->s_dev, 1))) { ! 181: printk ("ext_write_super: bread failed\n"); ! 182: return; ! 183: } ! 184: es = (struct ext_super_block *) bh->b_data; ! 185: es->s_firstfreeblock = (unsigned long) sb->s_zmap[0]; ! 186: es->s_freeblockscount = (unsigned long) sb->s_zmap[2]; ! 187: es->s_firstfreeinode = (unsigned long) sb->s_imap[0]; ! 188: es->s_freeinodescount = (unsigned long) sb->s_imap[2]; ! 189: bh->b_dirt = 1; ! 190: brelse (bh); ! 191: sb->s_dirt = 0; ! 192: #endif ! 193: } ! 194: ! 195: void ext_statfs (struct super_block *sb, struct statfs *buf) ! 196: { ! 197: long tmp; ! 198: ! 199: put_fs_long(EXT_SUPER_MAGIC, &buf->f_type); ! 200: put_fs_long(1024, &buf->f_bsize); ! 201: put_fs_long(sb->s_nzones << sb->s_log_zone_size, &buf->f_blocks); ! 202: tmp = ext_count_free_blocks(sb); ! 203: put_fs_long(tmp, &buf->f_bfree); ! 204: put_fs_long(tmp, &buf->f_bavail); ! 205: put_fs_long(sb->s_ninodes, &buf->f_files); ! 206: put_fs_long(ext_count_free_inodes(sb), &buf->f_ffree); ! 207: /* Don't know what value to put in buf->f_fsid */ ! 208: } ! 209: ! 210: static int _ext_bmap(struct inode * inode,int block,int create) ! 211: { ! 212: struct buffer_head * bh; ! 213: int i; ! 214: ! 215: if (block<0) { ! 216: printk("_ext_bmap: block<0"); ! 217: return 0; ! 218: } ! 219: if (block >= 9+256+256*256+256*256*256) { ! 220: printk("_ext_bmap: block>big"); ! 221: return 0; ! 222: } ! 223: if (block<9) { ! 224: if (create && !inode->i_data[block]) ! 225: if (inode->i_data[block]=ext_new_block(inode->i_dev)) { ! 226: inode->i_ctime=CURRENT_TIME; ! 227: inode->i_dirt=1; ! 228: } ! 229: return inode->i_data[block]; ! 230: } ! 231: block -= 9; ! 232: if (block<256) { ! 233: if (create && !inode->i_data[9]) ! 234: if (inode->i_data[9]=ext_new_block(inode->i_dev)) { ! 235: inode->i_dirt=1; ! 236: inode->i_ctime=CURRENT_TIME; ! 237: } ! 238: if (!inode->i_data[9]) ! 239: return 0; ! 240: if (!(bh = bread(inode->i_dev,inode->i_data[9]))) ! 241: return 0; ! 242: i = ((unsigned long *) (bh->b_data))[block]; ! 243: if (create && !i) ! 244: if (i=ext_new_block(inode->i_dev)) { ! 245: ((unsigned long *) (bh->b_data))[block]=i; ! 246: bh->b_dirt=1; ! 247: } ! 248: brelse(bh); ! 249: return i; ! 250: } ! 251: block -= 256; ! 252: if (block<256*256) { ! 253: if (create && !inode->i_data[10]) ! 254: if (inode->i_data[10]=ext_new_block(inode->i_dev)) { ! 255: inode->i_dirt=1; ! 256: inode->i_ctime=CURRENT_TIME; ! 257: } ! 258: if (!inode->i_data[10]) ! 259: return 0; ! 260: if (!(bh=bread(inode->i_dev,inode->i_data[10]))) ! 261: return 0; ! 262: i = ((unsigned long *)bh->b_data)[block>>8]; ! 263: if (create && !i) ! 264: if (i=ext_new_block(inode->i_dev)) { ! 265: ((unsigned long *) (bh->b_data))[block>>8]=i; ! 266: bh->b_dirt=1; ! 267: } ! 268: brelse(bh); ! 269: if (!i) ! 270: return 0; ! 271: if (!(bh=bread(inode->i_dev,i))) ! 272: return 0; ! 273: i = ((unsigned long *)bh->b_data)[block&255]; ! 274: if (create && !i) ! 275: if (i=ext_new_block(inode->i_dev)) { ! 276: ((unsigned long *) (bh->b_data))[block&255]=i; ! 277: bh->b_dirt=1; ! 278: } ! 279: brelse(bh); ! 280: return i; ! 281: } ! 282: printk("ext_bmap: triple indirection not yet implemented\n"); ! 283: return 0; ! 284: } ! 285: ! 286: int ext_bmap(struct inode * inode,int block) ! 287: { ! 288: return _ext_bmap(inode,block,0); ! 289: } ! 290: ! 291: int ext_create_block(struct inode * inode, int block) ! 292: { ! 293: return _ext_bmap(inode,block,1); ! 294: } ! 295: ! 296: void ext_read_inode(struct inode * inode) ! 297: { ! 298: struct buffer_head * bh; ! 299: struct ext_inode * raw_inode; ! 300: int block; ! 301: ! 302: #ifdef EXTFS_BITMAP ! 303: block = 2 + inode->i_sb->s_imap_blocks + inode->i_sb->s_zmap_blocks + ! 304: (inode->i_ino-1)/EXT_INODES_PER_BLOCK; ! 305: #endif ! 306: #ifdef EXTFS_FREELIST ! 307: block = 2 + (inode->i_ino-1)/EXT_INODES_PER_BLOCK; ! 308: #endif ! 309: if (!(bh=bread(inode->i_dev,block))) ! 310: panic("unable to read i-node block"); ! 311: raw_inode = ((struct ext_inode *) bh->b_data) + ! 312: (inode->i_ino-1)%EXT_INODES_PER_BLOCK; ! 313: inode->i_mode = raw_inode->i_mode; ! 314: inode->i_uid = raw_inode->i_uid; ! 315: inode->i_gid = raw_inode->i_gid; ! 316: inode->i_nlink = raw_inode->i_nlinks; ! 317: inode->i_size = raw_inode->i_size; ! 318: inode->i_mtime = inode->i_atime = inode->i_ctime = raw_inode->i_time; ! 319: if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) ! 320: inode->i_rdev = raw_inode->i_zone[0]; ! 321: else for (block = 0; block < 12; block++) ! 322: inode->i_data[block] = raw_inode->i_zone[block]; ! 323: brelse(bh); ! 324: inode->i_op = NULL; ! 325: if (S_ISREG(inode->i_mode)) ! 326: inode->i_op = &ext_file_inode_operations; ! 327: else if (S_ISDIR(inode->i_mode)) ! 328: inode->i_op = &ext_dir_inode_operations; ! 329: else if (S_ISLNK(inode->i_mode)) ! 330: inode->i_op = &ext_symlink_inode_operations; ! 331: else if (S_ISCHR(inode->i_mode)) ! 332: inode->i_op = &ext_chrdev_inode_operations; ! 333: else if (S_ISBLK(inode->i_mode)) ! 334: inode->i_op = &ext_blkdev_inode_operations; ! 335: else if (S_ISFIFO(inode->i_mode)) { ! 336: inode->i_op = &ext_fifo_inode_operations; ! 337: inode->i_size = 0; ! 338: inode->i_pipe = 1; ! 339: PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0; ! 340: PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0; ! 341: } ! 342: } ! 343: ! 344: void ext_write_inode(struct inode * inode) ! 345: { ! 346: struct buffer_head * bh; ! 347: struct ext_inode * raw_inode; ! 348: int block; ! 349: ! 350: #ifdef EXTFS_BITMAP ! 351: block = 2 + inode->i_sb->s_imap_blocks + inode->i_sb->s_zmap_blocks + ! 352: (inode->i_ino-1)/EXT_INODES_PER_BLOCK; ! 353: #endif ! 354: #ifdef EXTFS_FREELIST ! 355: block = 2 + (inode->i_ino-1)/EXT_INODES_PER_BLOCK; ! 356: #endif ! 357: if (!(bh=bread(inode->i_dev,block))) ! 358: panic("unable to read i-node block"); ! 359: raw_inode = ((struct ext_inode *)bh->b_data) + ! 360: (inode->i_ino-1)%EXT_INODES_PER_BLOCK; ! 361: raw_inode->i_mode = inode->i_mode; ! 362: raw_inode->i_uid = inode->i_uid; ! 363: raw_inode->i_gid = inode->i_gid; ! 364: raw_inode->i_nlinks = inode->i_nlink; ! 365: raw_inode->i_size = inode->i_size; ! 366: raw_inode->i_time = inode->i_mtime; ! 367: if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) ! 368: raw_inode->i_zone[0] = inode->i_rdev; ! 369: else for (block = 0; block < 12; block++) ! 370: raw_inode->i_zone[block] = inode->i_data[block]; ! 371: bh->b_dirt=1; ! 372: inode->i_dirt=0; ! 373: brelse(bh); ! 374: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.