diff --git a/libtcmu.c b/libtcmu.c index 11272183..46a6fbcc 100644 --- a/libtcmu.c +++ b/libtcmu.c @@ -1021,6 +1021,16 @@ bool tcmu_dev_get_unmap_enabled(struct tcmu_device *dev) return dev->unmap_enabled; } +void tcmu_dev_set_write_protect_enabled(struct tcmu_device *dev, bool enabled) +{ + dev->write_protect_enabled = enabled; +} + +bool tcmu_dev_get_write_protect_enabled(struct tcmu_device *dev) +{ + return dev->write_protect_enabled; +} + int tcmu_dev_get_fd(struct tcmu_device *dev) { return dev->fd; @@ -1060,7 +1070,7 @@ tcmu_dev_get_memory_info(struct tcmu_device *dev, void **base, /* get length of map from file */ ssize_t size; char *size_name; - + if (asprintf(&size_name, sizefmt, dev->dev_name) == -1) { tcmu_err("cannot construct device map size filename\n"); goto err_free; diff --git a/libtcmu_common.h b/libtcmu_common.h index 2897e1f0..20072a4a 100644 --- a/libtcmu_common.h +++ b/libtcmu_common.h @@ -138,6 +138,8 @@ void tcmu_dev_set_solid_state_media(struct tcmu_device *dev, bool solid_state); bool tcmu_dev_get_solid_state_media(struct tcmu_device *dev); void tcmu_dev_set_unmap_enabled(struct tcmu_device *dev, bool enabled); bool tcmu_dev_get_unmap_enabled(struct tcmu_device *dev); +void tcmu_dev_set_write_protect_enabled(struct tcmu_device *dev, bool enabled); +bool tcmu_dev_get_write_protect_enabled(struct tcmu_device *dev); struct tcmulib_handler *tcmu_dev_get_handler(struct tcmu_device *dev); void tcmu_dev_flush_ring(struct tcmu_device *dev); bool tcmu_dev_oooc_supported(struct tcmu_device* dev); diff --git a/libtcmu_priv.h b/libtcmu_priv.h index 9c53dbef..f5586569 100644 --- a/libtcmu_priv.h +++ b/libtcmu_priv.h @@ -55,6 +55,7 @@ struct tcmu_device { unsigned int write_cache_enabled:1; unsigned int solid_state_media:1; unsigned int unmap_enabled:1; + unsigned int write_protect_enabled:1; char dev_name[16]; /* e.g. "uio14" */ char tcm_hba_name[16]; /* e.g. "user_8" */ diff --git a/scsi.c b/scsi.c index 98afce97..386694b8 100644 --- a/scsi.c +++ b/scsi.c @@ -800,6 +800,14 @@ int tcmu_emulate_mode_sense( orig_buf[0] = used_len - 1; } + if (tcmu_dev_get_write_protect_enabled(dev)) { + if (sense_ten) { + orig_buf[3] |= 0x80; + } else { + orig_buf[2] |= 0x80; + } + } + tcmu_memcpy_into_iovec(iovec, iov_cnt, orig_buf, alloc_len); free(orig_buf); return TCMU_STS_OK;