/*
 * performs formatting of _device_ according to _fdata_
 * Note: The discipline's format_function is assumed to deliver formatting
 * commands to format a single unit of the device. In terms of the ECKD
 * devices this means CCWs are generated to format a single track.
 */
static int dasd_format(struct dasd_block *block, struct format_data_t *fdata)
{
    struct dasd_ccw_req *cqr;
    struct dasd_device *base;
    int rc;

    base = block->base;
    if (base->discipline->format_device == NULL)
        return -EPERM;

    if (base->state != DASD_STATE_BASIC) {
        DEV_MESSAGE(KERN_WARNING, base, "%s",
                    "dasd_format: device is not disabled! ");
        return -EBUSY;
    }

    DBF_DEV_EVENT(DBF_NOTICE, base,
                  "formatting units %d to %d (%d B blocks) flags %d",
                  fdata->start_unit,
                  fdata->stop_unit, fdata->blksize, fdata->intensity);

    /* Since dasdfmt keeps the device open after it was disabled,
     * there still exists an inode for this device.
     * We must update i_blkbits, otherwise we might get errors when
     * enabling the device later.
     */
    if (fdata->start_unit == 0) {
        struct block_device *bdev = bdget_disk(block->gdp, 0);
        bdev->bd_inode->i_blkbits = blksize_bits(fdata->blksize);
        bdput(bdev);
    }

    while (fdata->start_unit <= fdata->stop_unit) {
        cqr = base->discipline->format_device(base, fdata);
        if (IS_ERR(cqr))
            return PTR_ERR(cqr);
        rc = dasd_sleep_on_interruptible(cqr);
        dasd_sfree_request(cqr, cqr->memdev);
        if (rc) {
            if (rc != -ERESTARTSYS)
                DEV_MESSAGE(KERN_ERR, base,
                            " Formatting of unit %d failed "
                            "with rc = %d",
                            fdata->start_unit, rc);
            return rc;
        }
        fdata->start_unit++;
    }
    return 0;
}
/*
 * performs formatting of _device_ according to _fdata_
 * Note: The discipline's format_function is assumed to deliver formatting
 * commands to format a single unit of the device. In terms of the ECKD
 * devices this means CCWs are generated to format a single track.
 */
static int dasd_format(struct dasd_block *block, struct format_data_t *fdata)
{
	struct dasd_ccw_req *cqr;
	struct dasd_device *base;
	int rc;

	base = block->base;
	if (base->discipline->format_device == NULL)
		return -EPERM;

	if (base->state != DASD_STATE_BASIC) {
		pr_warning("%s: The DASD cannot be formatted while it is "
			   "enabled\n",  dev_name(&base->cdev->dev));
		return -EBUSY;
	}

	DBF_DEV_EVENT(DBF_NOTICE, base,
		      "formatting units %u to %u (%u B blocks) flags %u",
		      fdata->start_unit,
		      fdata->stop_unit, fdata->blksize, fdata->intensity);

	/* Since dasdfmt keeps the device open after it was disabled,
	 * there still exists an inode for this device.
	 * We must update i_blkbits, otherwise we might get errors when
	 * enabling the device later.
	 */
	if (fdata->start_unit == 0) {
		struct block_device *bdev = bdget_disk(block->gdp, 0);
		bdev->bd_inode->i_blkbits = blksize_bits(fdata->blksize);
		bdput(bdev);
	}

	while (fdata->start_unit <= fdata->stop_unit) {
		cqr = base->discipline->format_device(base, fdata);
		if (IS_ERR(cqr))
			return PTR_ERR(cqr);
		rc = dasd_sleep_on_interruptible(cqr);
		dasd_sfree_request(cqr, cqr->memdev);
		if (rc) {
			if (rc != -ERESTARTSYS)
				pr_err("%s: Formatting unit %d failed with "
				       "rc=%d\n", dev_name(&base->cdev->dev),
				       fdata->start_unit, rc);
			return rc;
		}
		fdata->start_unit++;
	}
	return 0;
}
Exemple #3
0
static unsigned long max_block(kdev_t dev)
{
	unsigned int retval = ~0U;
	int major = MAJOR(dev);

	if (blk_size[major]) {
		int minor = MINOR(dev);
		unsigned int blocks = blk_size[major][minor];
		if (blocks) {
			unsigned int size = block_size(dev);
			unsigned int sizebits = blksize_bits(size);
			blocks += (size-1) >> BLOCK_SIZE_BITS;
			retval = blocks << (BLOCK_SIZE_BITS - sizebits);
			if (sizebits > BLOCK_SIZE_BITS)
				retval = blocks >> (sizebits - BLOCK_SIZE_BITS);
		}
	}
	return retval;
}
Exemple #4
0
static int nullio_attach(struct iet_volume *lu, char *args)
{
	int err = 0;

	if ((err = parse_nullio_params(lu, args)) < 0) {
		eprintk("%d\n", err);
		goto out;
	}

	if (!lu->blk_shift)
		lu->blk_shift = blksize_bits(IET_DEF_BLOCK_SIZE);

	/* defaults to 64 GiB */
	if (!lu->blk_cnt)
		lu->blk_cnt = 1 << (36 - lu->blk_shift);

out:
	if (err < 0)
		nullio_detach(lu);
	return err;
}
Exemple #5
0
int set_blocksize(kdev_t dev, int size)
{
	int oldsize;
	struct block_device *bdev;

	/* Size must be a power of two, and between 512 and PAGE_SIZE */
	if (size > PAGE_SIZE || size < 512 || (size & (size-1)))
		return -EINVAL;

	/* Size cannot be smaller than the size supported by the device */
	if (size < get_hardsect_size(dev))
		return -EINVAL;

	/* No blocksize array? Implies hardcoded BLOCK_SIZE */
	if (!blksize_size[MAJOR(dev)]) {
		if (size == BLOCK_SIZE)
			return 0;
		return -EINVAL;
	}

	oldsize = blksize_size[MAJOR(dev)][MINOR(dev)];
	if (oldsize == size)
		return 0;

	if (!oldsize && size == BLOCK_SIZE) {
		blksize_size[MAJOR(dev)][MINOR(dev)] = size;
		return 0;
	}

	/* Ok, we're actually changing the blocksize.. */
	bdev = bdget(dev);
	sync_buffers(dev, 2);
	blksize_size[MAJOR(dev)][MINOR(dev)] = size;
	bdev->bd_inode->i_blkbits = blksize_bits(size);
	kill_bdev(bdev);
	bdput(bdev);
	return 0;
}
static int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
{
	int				ro;
	struct file			*filp = NULL;
	int				rc = -EINVAL;
	struct inode			*inode = NULL;
	loff_t				size;
	loff_t				num_sectors;
	loff_t				min_sectors;
	unsigned int			blkbits;
	unsigned int			blksize;

	/* R/W if we can, R/O if we must */
	ro = curlun->initially_ro;
	if (!ro) {
		filp = filp_open(filename, O_RDWR | O_LARGEFILE, 0);
		if (PTR_ERR(filp) == -EROFS || PTR_ERR(filp) == -EACCES)
			ro = 1;
	}
	if (ro)
		filp = filp_open(filename, O_RDONLY | O_LARGEFILE, 0);
	if (IS_ERR(filp)) {
		LINFO(curlun, "unable to open backing file: %s\n", filename);
		return PTR_ERR(filp);
	}

	if (!(filp->f_mode & FMODE_WRITE))
		ro = 1;

	inode = file_inode(filp);
	if ((!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))) {
		LINFO(curlun, "invalid file type: %s\n", filename);
		goto out;
	}

	/*
	 * If we can't read the file, it's no good.
	 * If we can't write the file, use it read-only.
	 */
	if (!(filp->f_op->read || filp->f_op->aio_read)) {
		LINFO(curlun, "file not readable: %s\n", filename);
		goto out;
	}
	if (!(filp->f_op->write || filp->f_op->aio_write))
		ro = 1;

	size = i_size_read(inode->i_mapping->host);
	if (size < 0) {
		LINFO(curlun, "unable to find file size: %s\n", filename);
		rc = (int) size;
		goto out;
	}

    /*
     * curlun->blksize remains the old value when switch from cdrom to udisk
     * so use the same blksie in cdrom and udisk
     */
#ifdef CONFIG_HUAWEI_USB
	if (inode->i_bdev) {
		blksize = bdev_logical_block_size(inode->i_bdev);
		blkbits = blksize_bits(blksize);
	} else {
		blksize = 512;
		blkbits = 9;
	}
#else
	if (curlun->cdrom) {
		blksize = 2048;
		blkbits = 11;
	} else if (inode->i_bdev) {
		blksize = bdev_logical_block_size(inode->i_bdev);
		blkbits = blksize_bits(blksize);
	} else {
		blksize = 512;
		blkbits = 9;
	}
#endif

	num_sectors = size >> blkbits; /* File size in logic-block-size blocks */
	min_sectors = 1;

#ifndef CONFIG_HUAWEI_USB
	if (curlun->cdrom) {
		min_sectors = 300;	/* Smallest track is 300 frames */
		if (num_sectors >= 256*60*75) {
			num_sectors = 256*60*75 - 1;
			LINFO(curlun, "file too big: %s\n", filename);
			LINFO(curlun, "using only first %d blocks\n",
					(int) num_sectors);
		}
	}
#endif

	if (num_sectors < min_sectors) {
		LINFO(curlun, "file too small: %s\n", filename);
		rc = -ETOOSMALL;
		goto out;
	}

	if (fsg_lun_is_open(curlun))
		fsg_lun_close(curlun);

	curlun->blksize = blksize;
	curlun->blkbits = blkbits;
	curlun->ro = ro;
	curlun->filp = filp;
	curlun->file_length = size;
	curlun->num_sectors = num_sectors;
	LDBG(curlun, "open backing file: %s\n", filename);
	return 0;

out:
	fput(filp);
	return rc;
}
Exemple #7
0
/*
 * fill in the superblock
 */
static int romfs_fill_super(struct super_block *sb, void *data, int silent)
{
	struct romfs_super_block *rsb;
	struct inode *root;
	unsigned long pos, img_size;
	const char *storage;
	size_t len;
	int ret;

#ifdef CONFIG_BLOCK
	if (!sb->s_mtd) {
		sb_set_blocksize(sb, ROMBSIZE);
	} else {
		sb->s_blocksize = ROMBSIZE;
		sb->s_blocksize_bits = blksize_bits(ROMBSIZE);
	}
#endif

	sb->s_maxbytes = 0xFFFFFFFF;
	sb->s_magic = ROMFS_MAGIC;
	sb->s_flags |= MS_RDONLY | MS_NOATIME;
	sb->s_op = &romfs_super_ops;

	/* read the image superblock and check it */
	rsb = kmalloc(512, GFP_KERNEL);
	if (!rsb)
		return -ENOMEM;

	sb->s_fs_info = (void *) 512;
	ret = romfs_dev_read(sb, 0, rsb, 512);
	if (ret < 0)
		goto error_rsb;

	img_size = be32_to_cpu(rsb->size);

	if (sb->s_mtd && img_size > sb->s_mtd->size)
		goto error_rsb_inval;

	sb->s_fs_info = (void *) img_size;

	if (rsb->word0 != ROMSB_WORD0 || rsb->word1 != ROMSB_WORD1 ||
	    img_size < ROMFH_SIZE) {
		if (!silent)
			printk(KERN_WARNING "VFS:"
			       " Can't find a romfs filesystem on dev %s.\n",
			       sb->s_id);
		goto error_rsb_inval;
	}

	if (romfs_checksum(rsb, min_t(size_t, img_size, 512))) {
		printk(KERN_ERR "ROMFS: bad initial checksum on dev %s.\n",
		       sb->s_id);
		goto error_rsb_inval;
	}

	storage = sb->s_mtd ? "MTD" : "the block layer";

	len = strnlen(rsb->name, ROMFS_MAXFN);
	if (!silent)
		printk(KERN_NOTICE "ROMFS: Mounting image '%*.*s' through %s\n",
		       (unsigned) len, (unsigned) len, rsb->name, storage);

	kfree(rsb);
	rsb = NULL;

	/* find the root directory */
	pos = (ROMFH_SIZE + len + 1 + ROMFH_PAD) & ROMFH_MASK;

	root = romfs_iget(sb, pos);
	if (IS_ERR(root))
		goto error;

	sb->s_root = d_alloc_root(root);
	if (!sb->s_root)
		goto error_i;

	return 0;

error_i:
	iput(root);
error:
	return -EINVAL;
error_rsb_inval:
	ret = -EINVAL;
error_rsb:
	kfree(rsb);
	return ret;
}
static int fsg_lun_open(struct fsg_lun *curlun, const char *filename)
{
	int				ro;
	struct file			*filp = NULL;
	int				rc = -EINVAL;
	struct inode			*inode = NULL;
	struct backing_dev_info		*bdi;
	loff_t				size;
	loff_t				num_sectors;
	loff_t				min_sectors;
	unsigned int			blkbits;
	unsigned int			blksize;

	/* R/W if we can, R/O if we must */
	ro = curlun->initially_ro;
	if (!ro) {
		filp = filp_open(filename, O_RDWR | O_LARGEFILE, 0);
		if (PTR_ERR(filp) == -EROFS || PTR_ERR(filp) == -EACCES)
			ro = 1;
	}
	if (ro)
		filp = filp_open(filename, O_RDONLY | O_LARGEFILE, 0);
	if (IS_ERR(filp)) {
		LINFO(curlun, "unable to open backing file: %s\n", filename);
		return PTR_ERR(filp);
	}

	if (!(filp->f_mode & FMODE_WRITE))
		ro = 1;

	inode = file_inode(filp);
	if ((!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))) {
		LINFO(curlun, "invalid file type: %s\n", filename);
		goto out;
	}

	/*
	 * If we can't read the file, it's no good.
	 * If we can't write the file, use it read-only.
	 */
	if (!(filp->f_op->read || filp->f_op->aio_read)) {
		LINFO(curlun, "file not readable: %s\n", filename);
		goto out;
	}
	if (!(filp->f_op->write || filp->f_op->aio_write))
		ro = 1;

	size = i_size_read(inode->i_mapping->host);
	if (size < 0) {
		LINFO(curlun, "unable to find file size: %s\n", filename);
		rc = (int) size;
		goto out;
	}

	if (curlun->cdrom) {
		blksize = 2048;
		blkbits = 11;
	} else if (inode->i_bdev) {
		blksize = bdev_logical_block_size(inode->i_bdev);
		blkbits = blksize_bits(blksize);

		bdi = &inode->i_bdev->bd_queue->backing_dev_info;
		if (bdi->capabilities & BDI_CAP_STRICTLIMIT) {
			curlun->max_ratio = bdi->max_ratio;
			curlun->nofua = 1;

			if (bdi_set_max_ratio(bdi, uicc_ums_max_ratio))
				pr_debug("%s, error in setting max_ratio\n",
						__func__);
		}
	} else {
		blksize = 512;
		blkbits = 9;
	}

	num_sectors = size >> blkbits; /* File size in logic-block-size blocks */
	min_sectors = 1;
	if (curlun->cdrom) {
		min_sectors = 300;	/* Smallest track is 300 frames */
		if (num_sectors >= 256*60*75) {
			num_sectors = 256*60*75 - 1;
			LINFO(curlun, "file too big: %s\n", filename);
			LINFO(curlun, "using only first %d blocks\n",
					(int) num_sectors);
		}
	}
	if (num_sectors < min_sectors) {
		LINFO(curlun, "file too small: %s\n", filename);
		rc = -ETOOSMALL;
		goto out;
	}

	if (fsg_lun_is_open(curlun))
		fsg_lun_close(curlun);

	curlun->blksize = blksize;
	curlun->blkbits = blkbits;
	curlun->ro = ro;
	curlun->filp = filp;
	curlun->file_length = size;
	curlun->num_sectors = num_sectors;

	LDBG(curlun, "open backing file: %s\n", filename);
	return 0;

out:
	fput(filp);
	return rc;
}