void ubifs_set_rootarg(struct ubifs_priv *priv, struct fs_device_d *fsdev) { struct ubi_volume_info vi = {}; struct ubi_device_info di = {}; struct mtd_info *mtd; char *str; ubi_get_volume_info(priv->ubi, &vi); ubi_get_device_info(vi.ubi_num, &di); mtd = di.mtd; str = basprintf("root=ubi0:%s ubi.mtd=%s rootfstype=ubifs", vi.name, mtd->cdev.partname); fsdev_set_linux_rootarg(fsdev, str); free(str); }
static int ubifs_fill_super(struct super_block *sb, void *data, int silent) { struct ubi_volume_desc *ubi = sb->s_fs_info; struct ubifs_info *c; struct inode *root; int err; c = kzalloc(sizeof(struct ubifs_info), GFP_KERNEL); if (!c) return -ENOMEM; spin_lock_init(&c->cnt_lock); spin_lock_init(&c->cs_lock); spin_lock_init(&c->buds_lock); spin_lock_init(&c->space_lock); spin_lock_init(&c->orphan_lock); init_rwsem(&c->commit_sem); mutex_init(&c->lp_mutex); mutex_init(&c->tnc_mutex); mutex_init(&c->log_mutex); mutex_init(&c->mst_mutex); mutex_init(&c->umount_mutex); init_waitqueue_head(&c->cmt_wq); c->buds = RB_ROOT; c->old_idx = RB_ROOT; c->size_tree = RB_ROOT; c->orph_tree = RB_ROOT; INIT_LIST_HEAD(&c->infos_list); INIT_LIST_HEAD(&c->idx_gc); INIT_LIST_HEAD(&c->replay_list); INIT_LIST_HEAD(&c->replay_buds); INIT_LIST_HEAD(&c->uncat_list); INIT_LIST_HEAD(&c->empty_list); INIT_LIST_HEAD(&c->freeable_list); INIT_LIST_HEAD(&c->frdi_idx_list); INIT_LIST_HEAD(&c->unclean_leb_list); INIT_LIST_HEAD(&c->old_buds); INIT_LIST_HEAD(&c->orph_list); INIT_LIST_HEAD(&c->orph_new); c->highest_inum = UBIFS_FIRST_INO; c->lhead_lnum = c->ltail_lnum = UBIFS_LOG_LNUM; ubi_get_volume_info(ubi, &c->vi); ubi_get_device_info(c->vi.ubi_num, &c->di); /* Re-open the UBI device in read-write mode */ c->ubi = ubi_open_volume(c->vi.ubi_num, c->vi.vol_id, UBI_READONLY); if (IS_ERR(c->ubi)) { err = PTR_ERR(c->ubi); goto out_free; } c->vfs_sb = sb; sb->s_fs_info = c; sb->s_magic = UBIFS_SUPER_MAGIC; sb->s_blocksize = UBIFS_BLOCK_SIZE; sb->s_blocksize_bits = UBIFS_BLOCK_SHIFT; sb->s_dev = c->vi.cdev; sb->s_maxbytes = c->max_inode_sz = key_max_inode_size(c); if (c->max_inode_sz > MAX_LFS_FILESIZE) sb->s_maxbytes = c->max_inode_sz = MAX_LFS_FILESIZE; if (c->rw_incompat) { ubifs_err("the file-system is not R/W-compatible"); ubifs_msg("on-flash format version is w%d/r%d, but software " "only supports up to version w%d/r%d", c->fmt_version, c->ro_compat_version, UBIFS_FORMAT_VERSION, UBIFS_RO_COMPAT_VERSION); return -EROFS; } mutex_lock(&c->umount_mutex); err = mount_ubifs(c); if (err) { ubifs_assert(err < 0); goto out_unlock; } /* Read the root inode */ root = ubifs_iget(sb, UBIFS_ROOT_INO); if (IS_ERR(root)) { err = PTR_ERR(root); goto out_umount; } sb->s_root = NULL; mutex_unlock(&c->umount_mutex); return 0; out_umount: ubifs_umount(c); out_unlock: mutex_unlock(&c->umount_mutex); ubi_close_volume(c->ubi); out_free: kfree(c); return err; }
/* * Set up our internal device. */ static void setup_device(struct ubiblk_dev *dev, int which) { memset (dev, 0, sizeof (struct ubiblk_dev)); spin_lock_init(&dev->lock); /* get each ubi device that we're working with. Each mtd device claimed * by the ubi layer is a device. Note that this can be a chip or a * partition. */ if(ubi_get_device_info(which, &dev->ubi_dev)) { printk("ubiblk: Failed to get device info for ubi%d\n", which); goto out_vfree; } /* each ubi device is either empty, corrupted, or contains some number * of volumes. For now, I'm assuming that there's exactly one volume, * and it's volume id is 0. This is a bit inapproriate, because ubi * volumes are supposed to be like partitions. The proper solution * would be to allow the ubi userspace tools to create partitions much * like fdisk would. */ dev->ubi_vol = ubi_open_volume(which, 0, UBI_READWRITE); if(IS_ERR(dev->ubi_vol)) { printk("Failed to open ubi volume 0 on device %d\n", which); dev->ubi_vol = 0; goto out_vfree; } dev->hardsect_size = dev->ubi_dev.min_io_size; dev->size = nsectors*dev->hardsect_size; /* setup blk dev queuing */ dev->queue = blk_init_queue(ubiblk_request, &dev->lock); if (dev->queue == NULL) goto out_vfree; blk_queue_hardsect_size(dev->queue, dev->hardsect_size); dev->queue->queuedata = dev; /* setup gendisk structure */ dev->gd = alloc_disk(UBIBLK_MINORS); if (! dev->gd) { printk (KERN_NOTICE "alloc_disk failure\n"); goto out_vfree; } dev->gd->major = ubiblk_major; dev->gd->first_minor = which*UBIBLK_MINORS; dev->gd->fops = &ubiblk_ops; dev->gd->queue = dev->queue; dev->gd->private_data = dev; snprintf (dev->gd->disk_name, 32, "ubiblk%c", which + 'a'); set_capacity(dev->gd, nsectors*(dev->hardsect_size/KERNEL_SECTOR_SIZE)); add_disk(dev->gd); return; out_vfree: if (dev->queue) blk_cleanup_queue(dev->queue); }