X-Git-Url: https://git.camperquake.de/gitweb.cgi?a=blobdiff_plain;f=module%2Fzfs%2Fzvol.c;h=0aaa268faa2a4793f59fd5013ad5560943a24090;hb=b18019d2d810585185493c62e9567fa85e51692c;hp=65a9240577c06aad84c0cd0edca6d283ed373a48;hpb=4c0d8e50b99b4f3b4a9b7bc67ac7fc4e406f5755;p=zfs.git diff --git a/module/zfs/zvol.c b/module/zfs/zvol.c index 65a9240..0aaa268 100644 --- a/module/zfs/zvol.c +++ b/module/zfs/zvol.c @@ -228,7 +228,7 @@ zvol_check_volsize(uint64_t volsize, uint64_t blocksize) * Ensure the zap is flushed then inform the VFS of the capacity change. */ static int -zvol_update_volsize(zvol_state_t *zv, uint64_t volsize) +zvol_update_volsize(zvol_state_t *zv, uint64_t volsize, objset_t *os) { struct block_device *bdev; dmu_tx_t *tx; @@ -236,7 +236,7 @@ zvol_update_volsize(zvol_state_t *zv, uint64_t volsize) ASSERT(MUTEX_HELD(&zvol_state_lock)); - tx = dmu_tx_create(zv->zv_objset); + tx = dmu_tx_create(os); dmu_tx_hold_zap(tx, ZVOL_ZAP_OBJ, TRUE, NULL); error = dmu_tx_assign(tx, TXG_WAIT); if (error) { @@ -244,27 +244,35 @@ zvol_update_volsize(zvol_state_t *zv, uint64_t volsize) return (error); } - error = zap_update(zv->zv_objset, ZVOL_ZAP_OBJ, "size", 8, 1, + error = zap_update(os, ZVOL_ZAP_OBJ, "size", 8, 1, &volsize, tx); dmu_tx_commit(tx); if (error) return (error); - error = dmu_free_long_range(zv->zv_objset, + error = dmu_free_long_range(os, ZVOL_OBJ, volsize, DMU_OBJECT_END); if (error) return (error); - zv->zv_volsize = volsize; - zv->zv_changed = 1; - bdev = bdget_disk(zv->zv_disk, 0); if (!bdev) - return EIO; + return (EIO); +/* + * 2.6.28 API change + * Added check_disk_size_change() helper function. + */ +#ifdef HAVE_CHECK_DISK_SIZE_CHANGE + set_capacity(zv->zv_disk, volsize >> 9); + zv->zv_volsize = volsize; + check_disk_size_change(zv->zv_disk, bdev); +#else + zv->zv_volsize = volsize; + zv->zv_changed = 1; + (void) check_disk_change(bdev); +#endif /* HAVE_CHECK_DISK_SIZE_CHANGE */ - error = check_disk_change(bdev); - ASSERT3U(error, !=, 0); bdput(bdev); return (0); @@ -311,7 +319,7 @@ zvol_set_volsize(const char *name, uint64_t volsize) goto out_doi; } - error = zvol_update_volsize(zv, volsize); + error = zvol_update_volsize(zv, volsize, os); out_doi: kmem_free(doi, sizeof(dmu_object_info_t)); out: @@ -526,6 +534,17 @@ zvol_write(void *arg) dmu_tx_t *tx; rl_t *rl; + if (req->cmd_flags & VDEV_REQ_FLUSH) + zil_commit(zv->zv_zilog, ZVOL_OBJ); + + /* + * Some requests are just for flush and nothing else. + */ + if (size == 0) { + blk_end_request(req, 0, size); + return; + } + rl = zfs_range_lock(&zv->zv_znode, offset, size, RL_WRITER); tx = dmu_tx_create(zv->zv_objset); @@ -542,12 +561,14 @@ zvol_write(void *arg) error = dmu_write_req(zv->zv_objset, ZVOL_OBJ, req, tx); if (error == 0) - zvol_log_write(zv, tx, offset, size, rq_is_sync(req)); + zvol_log_write(zv, tx, offset, size, + req->cmd_flags & VDEV_REQ_FUA); dmu_tx_commit(tx); zfs_range_unlock(rl); - if (rq_is_sync(req)) + if ((req->cmd_flags & VDEV_REQ_FUA) || + zv->zv_objset->os_sync == ZFS_SYNC_ALWAYS) zil_commit(zv->zv_zilog, ZVOL_OBJ); blk_end_request(req, -error, size); @@ -570,6 +591,11 @@ zvol_read(void *arg) int error; rl_t *rl; + if (size == 0) { + blk_end_request(req, 0, size); + return; + } + rl = zfs_range_lock(&zv->zv_znode, offset, size, RL_READER); error = dmu_read_req(zv->zv_objset, ZVOL_OBJ, req); @@ -619,7 +645,7 @@ zvol_request(struct request_queue *q) while ((req = blk_fetch_request(q)) != NULL) { size = blk_rq_bytes(req); - if (blk_rq_pos(req) + blk_rq_sectors(req) > + if (size != 0 && blk_rq_pos(req) + blk_rq_sectors(req) > get_capacity(zv->zv_disk)) { printk(KERN_INFO "%s: bad access: block=%llu, count=%lu\n", @@ -1054,6 +1080,12 @@ zvol_alloc(dev_t dev, const char *name) if (zv->zv_queue == NULL) goto out_kmem; +#ifdef HAVE_BLK_QUEUE_FLUSH + blk_queue_flush(zv->zv_queue, VDEV_REQ_FLUSH | VDEV_REQ_FUA); +#else + blk_queue_ordered(zv->zv_queue, QUEUE_ORDERED_DRAIN, NULL); +#endif /* HAVE_BLK_QUEUE_FLUSH */ + zv->zv_disk = alloc_disk(ZVOL_MINORS); if (zv->zv_disk == NULL) goto out_queue; @@ -1342,8 +1374,8 @@ zvol_fini(void) list_destroy(&zvol_state_list); } -module_param(zvol_major, uint, 0); +module_param(zvol_major, uint, 0444); MODULE_PARM_DESC(zvol_major, "Major number for zvol device"); -module_param(zvol_threads, uint, 0); +module_param(zvol_threads, uint, 0444); MODULE_PARM_DESC(zvol_threads, "Number of threads for zvol device");