Annotation of linux/fs/msdos/inode.c, revision 1.1.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.