--- linux/fs/msdos/inode.c 2018/04/24 18:12:17 1.1.1.1 +++ linux/fs/msdos/inode.c 2018/04/24 18:14:15 1.1.1.2 @@ -19,16 +19,16 @@ void msdos_put_inode(struct inode *inode inode->i_size = 0; msdos_truncate(inode); - depend = (struct inode *) inode->i_data[D_DEPEND]; + depend = MSDOS_I(inode)->i_depend; memset(inode,0,sizeof(struct inode)); if (depend) { - if ((struct inode *) depend->i_data[D_OLD] != inode) { + if (MSDOS_I(depend)->i_old != inode) { printk("Invalid link (0x%X): expected 0x%X, got " - "0x%X\r\n",(int) depend,(int) inode, - depend->i_data[D_OLD]); + "0x%X\n",(int) depend,(int) inode,(int) + MSDOS_I(depend)->i_old); panic("That's fatal"); } - depend->i_data[D_OLD] = 0; + MSDOS_I(depend)->i_old = NULL; iput(depend); } } @@ -104,7 +104,7 @@ struct super_block *msdos_read_super(str free_super(s); if (bh == NULL) { s->s_dev = 0; - printk("MSDOS bread failed\r\n"); + printk("MSDOS bread failed\n"); return NULL; } b = (struct msdos_boot_sector *) bh->b_data; @@ -123,9 +123,9 @@ struct super_block *msdos_read_super(str 0; MSDOS_SB(s)->fat_bits = MSDOS_SB(s)->clusters > MSDOS_FAT12 ? 16 : 12; brelse(bh); -printk("[MS-DOS FS Rel. alpha.6, FAT %d, check=%c, conv=%c]\r\n", +printk("[MS-DOS FS Rel. alpha.8, FAT %d, check=%c, conv=%c]\n", MSDOS_SB(s)->fat_bits,check,conversion); -printk("[me=0x%x,cs=%d,#f=%d,fs=%d,fl=%d,ds=%d,de=%d,data=%d,se=%d,ts=%d]\r\n", +printk("[me=0x%x,cs=%d,#f=%d,fs=%d,fl=%d,ds=%d,de=%d,data=%d,se=%d,ts=%d]\n", b->media,MSDOS_SB(s)->cluster_size,MSDOS_SB(s)->fats,MSDOS_SB(s)->fat_start, MSDOS_SB(s)->fat_length,MSDOS_SB(s)->dir_start,MSDOS_SB(s)->dir_entries, MSDOS_SB(s)->data_start,*(unsigned short *) &b->sectors,b->total_sect); @@ -133,10 +133,10 @@ printk("[me=0x%x,cs=%d,#f=%d,fs=%d,fl=%d || !b->cluster_size || MSDOS_SB(s)->clusters+2 > MSDOS_SB(s)-> fat_length*SECTOR_SIZE*8/MSDOS_SB(s)->fat_bits) { s->s_dev = 0; - printk("Unsupported FS parameters\r\n"); + printk("Unsupported FS parameters\n"); return NULL; } - if (!MSDOS_CAN_BMAP(MSDOS_SB(s))) printk("No bmap support\r\n"); + if (!MSDOS_CAN_BMAP(MSDOS_SB(s))) printk("No bmap support\n"); s->s_magic = MSDOS_SUPER_MAGIC; MSDOS_SB(s)->name_check = check; MSDOS_SB(s)->conversion = conversion; @@ -145,6 +145,9 @@ printk("[me=0x%x,cs=%d,#f=%d,fs=%d,fl=%d MSDOS_SB(s)->fs_uid = current->uid; MSDOS_SB(s)->fs_gid = current->gid; MSDOS_SB(s)->fs_umask = current->umask; + MSDOS_SB(s)->free_clusters = -1; /* don't know yet */ + MSDOS_SB(s)->fat_wait = NULL; + MSDOS_SB(s)->fat_lock = 0; if (!(s->s_mounted = iget(s->s_dev,MSDOS_ROOT_INO))) { s->s_dev = 0; printk("get root inode failed\n"); @@ -156,16 +159,21 @@ printk("[me=0x%x,cs=%d,#f=%d,fs=%d,fl=%d void msdos_statfs(struct super_block *sb,struct statfs *buf) { - int cluster_size,free,this; + int free,this; - cluster_size = MSDOS_SB(sb)->cluster_size; put_fs_long(sb->s_magic,&buf->f_type); - put_fs_long(SECTOR_SIZE,&buf->f_bsize); - put_fs_long(MSDOS_SB(sb)->clusters*cluster_size,&buf->f_blocks); - free = 0; - for (this = 2; this < MSDOS_SB(sb)->clusters+2; this++) - if (!fat_access(sb,this,-1)) free++; - free *= cluster_size; + put_fs_long(MSDOS_SB(sb)->cluster_size*SECTOR_SIZE,&buf->f_bsize); + put_fs_long(MSDOS_SB(sb)->clusters,&buf->f_blocks); + lock_fat(sb); + if (MSDOS_SB(sb)->free_clusters != -1) + free = MSDOS_SB(sb)->free_clusters; + else { + free = 0; + for (this = 2; this < MSDOS_SB(sb)->clusters+2; this++) + if (!fat_access(sb,this,-1)) free++; + MSDOS_SB(sb)->free_clusters = free; + } + unlock_fat(sb); put_fs_long(free,&buf->f_bfree); put_fs_long(free,&buf->f_bavail); put_fs_long(0,&buf->f_files); @@ -197,21 +205,26 @@ void msdos_read_inode(struct inode *inod struct msdos_dir_entry *raw_entry; int this; -/* printk("read inode %d\r\n",inode->i_ino); */ - inode->i_data[D_BUSY] = inode->i_data[D_DEPEND] = - inode->i_data[D_OLD] = 0; - inode->i_data[D_BINARY] = 1; +/* printk("read inode %d\n",inode->i_ino); */ + MSDOS_I(inode)->i_busy = 0; + MSDOS_I(inode)->i_depend = MSDOS_I(inode)->i_old = NULL; + MSDOS_I(inode)->i_binary = 1; inode->i_uid = MSDOS_SB(inode->i_sb)->fs_uid; inode->i_gid = MSDOS_SB(inode->i_sb)->fs_gid; if (inode->i_ino == MSDOS_ROOT_INO) { inode->i_mode = (0777 & ~MSDOS_SB(inode->i_sb)->fs_umask) | S_IFDIR; inode->i_op = &msdos_dir_inode_operations; - inode->i_nlink = 1; + inode->i_nlink = msdos_subdirs(inode)+2; + /* subdirs (neither . nor ..) plus . and "self" */ inode->i_size = MSDOS_SB(inode->i_sb)->dir_entries* sizeof(struct msdos_dir_entry); - inode->i_data[D_START] = 0; - inode->i_data[D_ATTRS] = 0; + inode->i_blksize = MSDOS_SB(inode->i_sb)->cluster_size* + SECTOR_SIZE; + inode->i_blocks = (inode->i_size+inode->i_blksize-1)/ + inode->i_blksize; + MSDOS_I(inode)->i_start = 0; + MSDOS_I(inode)->i_attrs = 0; inode->i_mtime = inode->i_atime = inode->i_ctime = 0; return; } @@ -219,16 +232,29 @@ void msdos_read_inode(struct inode *inod panic("unable to read i-node block"); raw_entry = &((struct msdos_dir_entry *) (bh->b_data)) [inode->i_ino & (MSDOS_DPB-1)]; - if (raw_entry->attr & ATTR_DIR) { + if ((raw_entry->attr & ATTR_DIR) && *raw_entry->name && *(unsigned char *) + raw_entry->name != DELETED_FLAG) { inode->i_mode = MSDOS_MKMODE(raw_entry->attr,0777 & ~MSDOS_SB(inode->i_sb)->fs_umask) | S_IFDIR; inode->i_op = &msdos_dir_inode_operations; - inode->i_nlink = 3; + MSDOS_I(inode)->i_start = raw_entry->start; + inode->i_nlink = msdos_subdirs(inode); + /* includes .., compensating for "self" */ +#ifdef DEBUG + if (!inode->i_nlink) { + printk("directory %d: i_nlink == 0\n",inode->i_ino); + inode->i_nlink = 1; + } +#endif inode->i_size = 0; - for (this = raw_entry->start; this && this != -1; this = - fat_access(inode->i_sb,this,-1)) - inode->i_size += SECTOR_SIZE*MSDOS_SB(inode->i_sb)-> - cluster_size; + if (this = raw_entry->start) + while (this != -1) { + inode->i_size += SECTOR_SIZE*MSDOS_SB(inode-> + i_sb)->cluster_size; + if (!(this = fat_access(inode->i_sb,this,-1))) + printk("Directory %d: bad FAT\n", + inode->i_ino); + } } else { inode->i_mode = MSDOS_MKMODE(raw_entry->attr,0666 & @@ -236,13 +262,17 @@ void msdos_read_inode(struct inode *inod inode->i_op = MSDOS_CAN_BMAP(MSDOS_SB(inode->i_sb)) ? &msdos_file_inode_operations : &msdos_file_inode_operations_no_bmap; + MSDOS_I(inode)->i_start = raw_entry->start; inode->i_nlink = 1; inode->i_size = raw_entry->size; } - inode->i_data[D_BINARY] = is_binary(MSDOS_SB(inode->i_sb)->conversion, + MSDOS_I(inode)->i_binary = is_binary(MSDOS_SB(inode->i_sb)->conversion, raw_entry->ext); - inode->i_data[D_START] = raw_entry->start; - inode->i_data[D_ATTRS] = raw_entry->attr & ATTR_UNUSED; + MSDOS_I(inode)->i_attrs = raw_entry->attr & ATTR_UNUSED; + /* this is as close to the truth as we can get ... */ + inode->i_blksize = MSDOS_SB(inode->i_sb)->cluster_size*SECTOR_SIZE; + inode->i_blocks = (inode->i_size+inode->i_blksize-1)/ + inode->i_blksize; inode->i_mtime = inode->i_atime = inode->i_ctime = date_dos2unix(raw_entry->time,raw_entry->date); brelse(bh); @@ -268,8 +298,9 @@ void msdos_write_inode(struct inode *ino raw_entry->attr = ATTR_NONE; raw_entry->size = inode->i_size; } - raw_entry->attr |= MSDOS_MKATTR(inode->i_mode) | inode->i_data[D_ATTRS]; - raw_entry->start = inode->i_data[D_START]; + raw_entry->attr |= MSDOS_MKATTR(inode->i_mode) | + MSDOS_I(inode)->i_attrs; + raw_entry->start = MSDOS_I(inode)->i_start; date_unix2dos(inode->i_mtime,&raw_entry->time,&raw_entry->date); bh->b_dirt = 1; brelse(bh);