@@ -111,6 +111,8 @@
/* don't allow encoded PR info to exceed 8K */
#define TCMU_PR_INFO_XATTR_MAX_SIZE 8192
+#define TCMU_PR_REG_MAX_RETRIES 5
+
#define TCMU_PR_INFO_XATTR_ENCODED_SCSI2_RSV_MAXLEN \
(TCMU_PR_IT_NEXUS_MAXLEN + sizeof("\n"))
@@ -2648,6 +2650,47 @@ tcmu_execute_pr_register_existing(struct tcmu_pr_info *pr_info,
return ret;
}
+static int tcmu_pr_info_replace(struct tcmu_dev *udev,
+ char *pr_xattr_old, int pr_xattr_len_old,
+ struct tcmu_pr_info *pr_info_new)
+{
+ int rc;
+ char *pr_xattr_new = NULL;
+ int pr_xattr_len_new = 0;
+
+ WARN_ON(!pr_xattr_old || !pr_info_new);
+
+ /* bump seqnum prior to xattr write. Not rolled back on failure */
+ pr_info_new->seq++;
+ rc = tcmu_pr_info_encode(pr_info_new, &pr_xattr_new,
+ &pr_xattr_len_new);
+
+ if (rc) {
+ pr_err("failed to encode PR xattr: %d\n", rc);
+ return rc;
+ }
+
+ if (pr_xattr_len_new > TCMU_PR_INFO_XATTR_MAX_SIZE) {
+ pr_err("unable to store oversize (%d) PR info: %s\n",
+ pr_xattr_len_new, pr_xattr_new);
+ rc = -E2BIG;
+ goto err_xattr_new_free;
+ }
+
+ rc = tcmu_set_dev_pr_info(udev, pr_xattr_new);
+ if (rc) {
+ pr_err("failed to set PR xattr: %d\n", rc);
+ goto err_xattr_new_free;
+ }
+
+ pr_debug("successfully replaced PR info\n");
+ rc = 0;
+err_xattr_new_free:
+ kfree(pr_xattr_new);
+
+ return 0;
+}
+
static int tcmu_configure_device(struct se_device *dev)
{
struct tcmu_dev *udev = TCMU_DEV(dev);
This patch added a function tcmu_pr_info_replace() which can help update Persistent Reservation information stored on a TCMU device. It will generate a new string based on the provided struct tcmu_pr_info struct, then write it to the device.For example, If we are using RBD, it will update PR info to RBD meatada. Signed-off-by: Zhu Lingshan <lszhu@suse.com> --- drivers/target/target_core_user.c | 43 +++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+)