Annotation of linux/fs/msdos/inode.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *  linux/fs/msdos/inode.c
        !             3:  *
        !             4:  *  Written 1992 by Werner Almesberger
        !             5:  */
        !             6: 
        !             7: #include <linux/msdos_fs.h>
        !             8: #include <linux/kernel.h>
        !             9: #include <linux/sched.h>
        !            10: #include <linux/errno.h>
        !            11: #include <linux/string.h>
        !            12: #include <linux/stat.h>
        !            13: 
        !            14: #include <asm/segment.h>
        !            15: 
        !            16: void msdos_put_inode(struct inode *inode)
        !            17: {
        !            18:        struct inode *depend;
        !            19: 
        !            20:        inode->i_size = 0;
        !            21:        msdos_truncate(inode);
        !            22:        depend = (struct inode *) inode->i_data[D_DEPEND];
        !            23:        memset(inode,0,sizeof(struct inode));
        !            24:        if (depend) {
        !            25:                if ((struct inode *) depend->i_data[D_OLD] != inode) {
        !            26:                        printk("Invalid link (0x%X): expected 0x%X, got "
        !            27:                            "0x%X\r\n",(int) depend,(int) inode,
        !            28:                            depend->i_data[D_OLD]);
        !            29:                        panic("That's fatal");
        !            30:                }
        !            31:                depend->i_data[D_OLD] = 0;
        !            32:                iput(depend);
        !            33:        }
        !            34: }
        !            35: 
        !            36: 
        !            37: void msdos_put_super(struct super_block *sb)
        !            38: {
        !            39:        cache_inval_dev(sb->s_dev);
        !            40:        lock_super(sb);
        !            41:        sb->s_dev = 0;
        !            42:        free_super(sb);
        !            43:        return;
        !            44: }
        !            45: 
        !            46: 
        !            47: static struct super_operations msdos_sops = { 
        !            48:        msdos_read_inode,
        !            49:        msdos_write_inode,
        !            50:        msdos_put_inode,
        !            51:        msdos_put_super,
        !            52:        NULL, /* added in 0.96c */
        !            53:        msdos_statfs
        !            54: };
        !            55: 
        !            56: 
        !            57: static int parse_options(char *options,char *check,char *conversion)
        !            58: {
        !            59:        char *this,*value;
        !            60: 
        !            61:        *check = 'n';
        !            62:        *conversion = 'b';
        !            63:        if (!options) return 1;
        !            64:        for (this = strtok(options,","); this; this = strtok(NULL,",")) {
        !            65:                if (value = strchr(this,'=')) *value++ = 0;
        !            66:                if (!strcmp(this,"check") && value) {
        !            67:                        if (value[0] && !value[1] && strchr("rns",*value))
        !            68:                                *check = *value;
        !            69:                        else if (!strcmp(value,"relaxed")) *check = 'r';
        !            70:                        else if (!strcmp(value,"normal")) *check = 'n';
        !            71:                        else if (!strcmp(value,"strict")) *check = 's';
        !            72:                        else return 0;
        !            73:                }
        !            74:                else if (!strcmp(this,"conv") && value) {
        !            75:                        if (value[0] && !value[1] && strchr("bta",*value))
        !            76:                                *conversion = *value;
        !            77:                        else if (!strcmp(value,"binary")) *conversion = 'b';
        !            78:                        else if (!strcmp(value,"text")) *conversion = 't';
        !            79:                        else if (!strcmp(value,"auto")) *conversion = 'a';
        !            80:                        else return 0;
        !            81:                }
        !            82:                else return 0;
        !            83:        }
        !            84:        return 1;
        !            85: }
        !            86: 
        !            87: 
        !            88: /* Read the super block of an MS-DOS FS. */
        !            89: 
        !            90: struct super_block *msdos_read_super(struct super_block *s,void *data)
        !            91: {
        !            92:        struct buffer_head *bh;
        !            93:        struct msdos_boot_sector *b;
        !            94:        int data_sectors;
        !            95:        char check,conversion;
        !            96: 
        !            97:        if (!parse_options((char *) data,&check,&conversion)) {
        !            98:                s->s_dev = 0;
        !            99:                return NULL;
        !           100:        }
        !           101:        cache_init();
        !           102:        lock_super(s);
        !           103:        bh = bread(s->s_dev, 0, BLOCK_SIZE);
        !           104:        free_super(s);
        !           105:        if (bh == NULL) {
        !           106:                s->s_dev = 0;
        !           107:                printk("MSDOS bread failed\r\n");
        !           108:                return NULL;
        !           109:        }
        !           110:        b = (struct msdos_boot_sector *) bh->b_data;
        !           111:        s->s_blocksize = 1024;  /* we cannot handle anything else yet */
        !           112:        MSDOS_SB(s)->cluster_size = b->cluster_size;
        !           113:        MSDOS_SB(s)->fats = b->fats;
        !           114:        MSDOS_SB(s)->fat_start = b->reserved;
        !           115:        MSDOS_SB(s)->fat_length = b->fat_length;
        !           116:        MSDOS_SB(s)->dir_start = b->reserved+b->fats*b->fat_length;
        !           117:        MSDOS_SB(s)->dir_entries = *((unsigned short *) &b->dir_entries);
        !           118:        MSDOS_SB(s)->data_start = MSDOS_SB(s)->dir_start+((MSDOS_SB(s)->
        !           119:            dir_entries << 5) >> 9);
        !           120:        data_sectors = (*((unsigned short *) &b->sectors) ? *((unsigned short *)
        !           121:            &b->sectors) : b->total_sect)-MSDOS_SB(s)->data_start;
        !           122:        MSDOS_SB(s)->clusters = b->cluster_size ? data_sectors/b->cluster_size :
        !           123:            0;
        !           124:        MSDOS_SB(s)->fat_bits = MSDOS_SB(s)->clusters > MSDOS_FAT12 ? 16 : 12;
        !           125:        brelse(bh);
        !           126: printk("[MS-DOS FS Rel. alpha.6, FAT %d, check=%c, conv=%c]\r\n",
        !           127:   MSDOS_SB(s)->fat_bits,check,conversion);
        !           128: printk("[me=0x%x,cs=%d,#f=%d,fs=%d,fl=%d,ds=%d,de=%d,data=%d,se=%d,ts=%d]\r\n",
        !           129:   b->media,MSDOS_SB(s)->cluster_size,MSDOS_SB(s)->fats,MSDOS_SB(s)->fat_start,
        !           130:   MSDOS_SB(s)->fat_length,MSDOS_SB(s)->dir_start,MSDOS_SB(s)->dir_entries,
        !           131:   MSDOS_SB(s)->data_start,*(unsigned short *) &b->sectors,b->total_sect);
        !           132:        if (!MSDOS_SB(s)->fats || (MSDOS_SB(s)->dir_entries & (MSDOS_DPS-1))
        !           133:            || !b->cluster_size || MSDOS_SB(s)->clusters+2 > MSDOS_SB(s)->
        !           134:                fat_length*SECTOR_SIZE*8/MSDOS_SB(s)->fat_bits) {
        !           135:                s->s_dev = 0;
        !           136:                printk("Unsupported FS parameters\r\n");
        !           137:                return NULL;
        !           138:        }
        !           139:        if (!MSDOS_CAN_BMAP(MSDOS_SB(s))) printk("No bmap support\r\n");
        !           140:        s->s_magic = MSDOS_SUPER_MAGIC;
        !           141:        MSDOS_SB(s)->name_check = check;
        !           142:        MSDOS_SB(s)->conversion = conversion;
        !           143:        /* set up enough so that it can read an inode */
        !           144:        s->s_op = &msdos_sops;
        !           145:        MSDOS_SB(s)->fs_uid = current->uid;
        !           146:        MSDOS_SB(s)->fs_gid = current->gid;
        !           147:        MSDOS_SB(s)->fs_umask = current->umask;
        !           148:        if (!(s->s_mounted = iget(s->s_dev,MSDOS_ROOT_INO))) {
        !           149:                s->s_dev = 0;
        !           150:                printk("get root inode failed\n");
        !           151:                return NULL;
        !           152:        }
        !           153:        return s;
        !           154: }
        !           155: 
        !           156: 
        !           157: void msdos_statfs(struct super_block *sb,struct statfs *buf)
        !           158: {
        !           159:        int cluster_size,free,this;
        !           160: 
        !           161:        cluster_size = MSDOS_SB(sb)->cluster_size;
        !           162:        put_fs_long(sb->s_magic,&buf->f_type);
        !           163:        put_fs_long(SECTOR_SIZE,&buf->f_bsize);
        !           164:        put_fs_long(MSDOS_SB(sb)->clusters*cluster_size,&buf->f_blocks);
        !           165:        free = 0;
        !           166:        for (this = 2; this < MSDOS_SB(sb)->clusters+2; this++)
        !           167:                if (!fat_access(sb,this,-1)) free++;
        !           168:        free *= cluster_size;
        !           169:        put_fs_long(free,&buf->f_bfree);
        !           170:        put_fs_long(free,&buf->f_bavail);
        !           171:        put_fs_long(0,&buf->f_files);
        !           172:        put_fs_long(0,&buf->f_ffree);
        !           173: }
        !           174: 
        !           175: 
        !           176: int msdos_bmap(struct inode *inode,int block)
        !           177: {
        !           178:        struct msdos_sb_info *sb;
        !           179:        int cluster,offset;
        !           180: 
        !           181:        sb = MSDOS_SB(inode->i_sb);
        !           182:        if ((sb->cluster_size & 1) || (sb->data_start & 1)) return 0;
        !           183:        if (inode->i_ino == MSDOS_ROOT_INO) {
        !           184:                if (sb->dir_start & 1) return 0;
        !           185:                return (sb->dir_start >> 1)+block;
        !           186:        }
        !           187:        cluster = (block*2)/sb->cluster_size;
        !           188:        offset = (block*2) % sb->cluster_size;
        !           189:        if (!(cluster = get_cluster(inode,cluster))) return 0;
        !           190:        return ((cluster-2)*sb->cluster_size+sb->data_start+offset) >> 1;
        !           191: }
        !           192: 
        !           193: 
        !           194: void msdos_read_inode(struct inode *inode)
        !           195: {
        !           196:        struct buffer_head *bh;
        !           197:        struct msdos_dir_entry *raw_entry;
        !           198:        int this;
        !           199: 
        !           200: /* printk("read inode %d\r\n",inode->i_ino); */
        !           201:        inode->i_data[D_BUSY] = inode->i_data[D_DEPEND] =
        !           202:            inode->i_data[D_OLD] = 0;
        !           203:        inode->i_data[D_BINARY] = 1;
        !           204:        inode->i_uid = MSDOS_SB(inode->i_sb)->fs_uid;
        !           205:        inode->i_gid = MSDOS_SB(inode->i_sb)->fs_gid;
        !           206:        if (inode->i_ino == MSDOS_ROOT_INO) {
        !           207:                inode->i_mode = (0777 & ~MSDOS_SB(inode->i_sb)->fs_umask) |
        !           208:                    S_IFDIR;
        !           209:                inode->i_op = &msdos_dir_inode_operations;
        !           210:                inode->i_nlink = 1;
        !           211:                inode->i_size = MSDOS_SB(inode->i_sb)->dir_entries*
        !           212:                    sizeof(struct msdos_dir_entry);
        !           213:                inode->i_data[D_START] = 0;
        !           214:                inode->i_data[D_ATTRS] = 0;
        !           215:                inode->i_mtime = inode->i_atime = inode->i_ctime = 0;
        !           216:                return;
        !           217:        }
        !           218:        if (!(bh = bread(inode->i_dev,inode->i_ino >> MSDOS_DPB_BITS, BLOCK_SIZE)))
        !           219:            panic("unable to read i-node block");
        !           220:        raw_entry = &((struct msdos_dir_entry *) (bh->b_data))
        !           221:            [inode->i_ino & (MSDOS_DPB-1)];
        !           222:        if (raw_entry->attr & ATTR_DIR) {
        !           223:                inode->i_mode = MSDOS_MKMODE(raw_entry->attr,0777 &
        !           224:                    ~MSDOS_SB(inode->i_sb)->fs_umask) | S_IFDIR;
        !           225:                inode->i_op = &msdos_dir_inode_operations;
        !           226:                inode->i_nlink = 3;
        !           227:                inode->i_size = 0;
        !           228:                for (this = raw_entry->start; this && this != -1; this =
        !           229:                    fat_access(inode->i_sb,this,-1))
        !           230:                        inode->i_size += SECTOR_SIZE*MSDOS_SB(inode->i_sb)->
        !           231:                            cluster_size;
        !           232:        }
        !           233:        else {
        !           234:                inode->i_mode = MSDOS_MKMODE(raw_entry->attr,0666 &
        !           235:                    ~MSDOS_SB(inode->i_sb)->fs_umask) | S_IFREG;
        !           236:                inode->i_op = MSDOS_CAN_BMAP(MSDOS_SB(inode->i_sb)) ? 
        !           237:                    &msdos_file_inode_operations :
        !           238:                    &msdos_file_inode_operations_no_bmap;
        !           239:                inode->i_nlink = 1;
        !           240:                inode->i_size = raw_entry->size;
        !           241:        }
        !           242:        inode->i_data[D_BINARY] = is_binary(MSDOS_SB(inode->i_sb)->conversion,
        !           243:            raw_entry->ext);
        !           244:        inode->i_data[D_START] = raw_entry->start;
        !           245:        inode->i_data[D_ATTRS] = raw_entry->attr & ATTR_UNUSED;
        !           246:        inode->i_mtime = inode->i_atime = inode->i_ctime =
        !           247:            date_dos2unix(raw_entry->time,raw_entry->date);
        !           248:        brelse(bh);
        !           249: }
        !           250: 
        !           251: 
        !           252: void msdos_write_inode(struct inode *inode)
        !           253: {
        !           254:        struct buffer_head *bh;
        !           255:        struct msdos_dir_entry *raw_entry;
        !           256: 
        !           257:        inode->i_dirt = 0;
        !           258:        if (inode->i_ino == MSDOS_ROOT_INO || !inode->i_nlink) return;
        !           259:        if (!(bh = bread(inode->i_dev,inode->i_ino >> MSDOS_DPB_BITS, BLOCK_SIZE)))
        !           260:            panic("unable to read i-node block");
        !           261:        raw_entry = &((struct msdos_dir_entry *) (bh->b_data))
        !           262:            [inode->i_ino & (MSDOS_DPB-1)];
        !           263:        if (S_ISDIR(inode->i_mode)) {
        !           264:                raw_entry->attr = ATTR_DIR;
        !           265:                raw_entry->size = 0;
        !           266:        }
        !           267:        else {
        !           268:                raw_entry->attr = ATTR_NONE;
        !           269:                raw_entry->size = inode->i_size;
        !           270:        }
        !           271:        raw_entry->attr |= MSDOS_MKATTR(inode->i_mode) | inode->i_data[D_ATTRS];
        !           272:        raw_entry->start = inode->i_data[D_START];
        !           273:        date_unix2dos(inode->i_mtime,&raw_entry->time,&raw_entry->date);
        !           274:        bh->b_dirt = 1;
        !           275:        brelse(bh);
        !           276: }

unix.superglobalmegacorp.com

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