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

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

unix.superglobalmegacorp.com

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