Annotation of linux/fs/ext/inode.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.