static ssize_t max_ratio_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct backing_dev_info *bdi = dev_get_drvdata(dev); unsigned int ratio; ssize_t ret; ret = kstrtouint(buf, 10, &ratio); if (ret < 0) return ret; ret = bdi_set_max_ratio(bdi, ratio); if (!ret) ret = count; return ret; }
static void fsg_lun_close(struct fsg_lun *curlun) { struct inode *inode = NULL; struct backing_dev_info *bdi; if (curlun->filp) { inode = file_inode(curlun->filp); if (inode->i_bdev) { bdi = &inode->i_bdev->bd_queue->backing_dev_info; if ((bdi->capabilities & BDI_CAP_STRICTLIMIT) && bdi_set_max_ratio(bdi, curlun->max_ratio)) pr_debug("%s, error in setting max_ratio\n", __func__); } LDBG(curlun, "close backing file\n"); fput(curlun->filp); curlun->filp = NULL; } }
static struct fuse_conn *new_conn(struct super_block *sb) { struct fuse_conn *fc; int err; fc = kzalloc(sizeof(*fc), GFP_KERNEL); if (fc) { spin_lock_init(&fc->lock); mutex_init(&fc->inst_mutex); atomic_set(&fc->count, 1); init_waitqueue_head(&fc->waitq); init_waitqueue_head(&fc->blocked_waitq); init_waitqueue_head(&fc->reserved_req_waitq); INIT_LIST_HEAD(&fc->pending); INIT_LIST_HEAD(&fc->processing); INIT_LIST_HEAD(&fc->io); INIT_LIST_HEAD(&fc->interrupts); INIT_LIST_HEAD(&fc->bg_queue); atomic_set(&fc->num_waiting, 0); fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE; fc->bdi.unplug_io_fn = default_unplug_io_fn; /* fuse does it's own writeback accounting */ fc->bdi.capabilities = BDI_CAP_NO_ACCT_WB; fc->dev = sb->s_dev; err = bdi_init(&fc->bdi); if (err) goto error_kfree; if (sb->s_bdev) { err = bdi_register(&fc->bdi, NULL, "%u:%u-fuseblk", MAJOR(fc->dev), MINOR(fc->dev)); } else { err = bdi_register_dev(&fc->bdi, fc->dev); } if (err) goto error_bdi_destroy; /* * For a single fuse filesystem use max 1% of dirty + * writeback threshold. * * This gives about 1M of write buffer for memory maps on a * machine with 1G and 10% dirty_ratio, which should be more * than enough. * * Privileged users can raise it by writing to * * /sys/class/bdi/<bdi>/max_ratio */ bdi_set_max_ratio(&fc->bdi, 1); fc->reqctr = 0; fc->blocked = 1; fc->attr_version = 1; get_random_bytes(&fc->scramble_key, sizeof(fc->scramble_key)); } return fc; error_bdi_destroy: bdi_destroy(&fc->bdi); error_kfree: mutex_destroy(&fc->inst_mutex); kfree(fc); return NULL; }
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; }