/* * 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; }
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; }
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; }
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; }
/* * 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; }