static int efs_fill_super(struct super_block *s, void *d, int silent) { struct efs_sb_info *sb; struct buffer_head *bh; struct inode *root; int ret = -EINVAL; sb = kzalloc(sizeof(struct efs_sb_info), GFP_KERNEL); if (!sb) return -ENOMEM; s->s_fs_info = sb; s->s_magic = EFS_SUPER_MAGIC; if (!sb_set_blocksize(s, EFS_BLOCKSIZE)) { printk(KERN_ERR "EFS: device does not support %d byte blocks\n", EFS_BLOCKSIZE); goto out_no_fs_ul; } /* read the vh (volume header) block */ bh = sb_bread(s, 0); if (!bh) { printk(KERN_ERR "EFS: cannot read volume header\n"); goto out_no_fs_ul; } /* * if this returns zero then we didn't find any partition table. * this isn't (yet) an error - just assume for the moment that * the device is valid and go on to search for a superblock. */ sb->fs_start = efs_validate_vh((struct volume_header *) bh->b_data); brelse(bh); if (sb->fs_start == -1) { goto out_no_fs_ul; } bh = sb_bread(s, sb->fs_start + EFS_SUPER); if (!bh) { printk(KERN_ERR "EFS: cannot read superblock\n"); goto out_no_fs_ul; } if (efs_validate_super(sb, (struct efs_super *) bh->b_data)) { #ifdef DEBUG printk(KERN_WARNING "EFS: invalid superblock at block %u\n", sb->fs_start + EFS_SUPER); #endif brelse(bh); goto out_no_fs_ul; } brelse(bh); if (!(s->s_flags & MS_RDONLY)) { #ifdef DEBUG printk(KERN_INFO "EFS: forcing read-only mode\n"); #endif s->s_flags |= MS_RDONLY; } s->s_op = &efs_superblock_operations; s->s_export_op = &efs_export_ops; root = efs_iget(s, EFS_ROOTINODE); if (IS_ERR(root)) { printk(KERN_ERR "EFS: get root inode failed\n"); ret = PTR_ERR(root); goto out_no_fs; } s->s_root = d_make_root(root); if (!(s->s_root)) { printk(KERN_ERR "EFS: get root dentry failed\n"); ret = -ENOMEM; goto out_no_fs; } return 0; out_no_fs_ul: out_no_fs: s->s_fs_info = NULL; kfree(sb); return ret; }
struct super_block *efs_read_super(struct super_block *s, void *d, int silent) { kdev_t dev = s->s_dev; struct efs_sb_info *sb; struct buffer_head *bh; MOD_INC_USE_COUNT; lock_super(s); sb = SUPER_INFO(s); set_blocksize(dev, EFS_BLOCKSIZE); /* read the vh (volume header) block */ bh = bread(dev, 0, EFS_BLOCKSIZE); if (!bh) { printk(KERN_ERR "EFS: cannot read volume header\n"); goto out_no_fs_ul; } /* * if this returns zero then we didn't find any partition table. * this isn't (yet) an error - just assume for the moment that * the device is valid and go on to search for a superblock. */ sb->fs_start = efs_validate_vh((struct volume_header *) bh->b_data); brelse(bh); if (sb->fs_start == -1) { goto out_no_fs_ul; } bh = bread(dev, sb->fs_start + EFS_SUPER, EFS_BLOCKSIZE); if (!bh) { printk(KERN_ERR "EFS: cannot read superblock\n"); goto out_no_fs_ul; } if (efs_validate_super(sb, (struct efs_super *) bh->b_data)) { #ifdef DEBUG printk(KERN_WARNING "EFS: invalid superblock at block %u\n", sb->fs_start + EFS_SUPER); #endif brelse(bh); goto out_no_fs_ul; } brelse(bh); s->s_magic = EFS_SUPER_MAGIC; s->s_blocksize = EFS_BLOCKSIZE; s->s_blocksize_bits = EFS_BLOCKSIZE_BITS; if (!(s->s_flags & MS_RDONLY)) { #ifdef DEBUG printk(KERN_INFO "EFS: forcing read-only mode\n"); #endif s->s_flags |= MS_RDONLY; } s->s_op = &efs_superblock_operations; s->s_dev = dev; s->s_root = d_alloc_root(iget(s, EFS_ROOTINODE), NULL); unlock_super(s); if (!(s->s_root)) { printk(KERN_ERR "EFS: get root inode failed\n"); goto out_no_fs; } if (check_disk_change(s->s_dev)) { printk(KERN_ERR "EFS: device changed\n"); goto out_no_fs; } return(s); out_no_fs_ul: unlock_super(s); out_no_fs: s->s_dev = 0; MOD_DEC_USE_COUNT; return(NULL); }