Re: [PATCH 10/13] target: Allocate aptpl_buf inside update_and_write_aptpl()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 2013-05-15 at 17:36 -0700, Andy Grover wrote:
> Instead of taking the buffer and length, update_and_write_aptpl() will
> allocate the buffer as needed, and then free it. Instead, the function
> takes an 'aptpl' boolean parameter.
> 
> This enables us to remove memory alloc/frees from struct
> t10_pr_registration and other spots.
> 
> In emulate_pro_register, this patch also uses if/else for handling the
> two values for sa_res_key, which (at least to me) seems easier to
> understand.
> 
> There is a slight loss of functionality because each callsite doesn't get
> its own pr_debug any more, but this info can be cleaned via ftrace if
> necessary and I think the shorter code is worth it.

This patch is complex enough that mixing together different changes
makes it very confusing to review.

Please split up the actual allocate aptpl_buf inside
update_and_write_aptpl() part, and the emulate_pro_register()
reshuffling part.

--nab

> 
> Signed-off-by: Andy Grover <agrover@xxxxxxxxxx>
> ---
>  drivers/target/target_core_pr.c   |  239 ++++++++++---------------------------
>  include/target/target_core_base.h |    2 -
>  2 files changed, 66 insertions(+), 175 deletions(-)
> 
> diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c
> index 3dd3fe5..6db3a46 100644
> --- a/drivers/target/target_core_pr.c
> +++ b/drivers/target/target_core_pr.c
> @@ -606,13 +606,6 @@ static struct t10_pr_registration *__core_scsi3_do_alloc_registration(
>  		return NULL;
>  	}
>  
> -	pr_reg->pr_aptpl_buf = kzalloc(PR_APTPL_BUF_LEN, GFP_ATOMIC);
> -	if (!pr_reg->pr_aptpl_buf) {
> -		pr_err("Unable to allocate pr_reg->pr_aptpl_buf\n");
> -		kmem_cache_free(t10_pr_reg_cache, pr_reg);
> -		return NULL;
> -	}
> -
>  	INIT_LIST_HEAD(&pr_reg->pr_reg_list);
>  	INIT_LIST_HEAD(&pr_reg->pr_reg_abort_list);
>  	INIT_LIST_HEAD(&pr_reg->pr_reg_aptpl_list);
> @@ -803,7 +796,6 @@ int core_scsi3_alloc_aptpl_registration(
>  		pr_err("Unable to allocate struct t10_pr_registration\n");
>  		return -ENOMEM;
>  	}
> -	pr_reg->pr_aptpl_buf = kzalloc(PR_APTPL_BUF_LEN, GFP_KERNEL);
>  
>  	INIT_LIST_HEAD(&pr_reg->pr_reg_list);
>  	INIT_LIST_HEAD(&pr_reg->pr_reg_abort_list);
> @@ -1272,7 +1264,6 @@ static void __core_scsi3_free_registration(
>  	if (!preempt_and_abort_list) {
>  		pr_reg->pr_reg_deve = NULL;
>  		pr_reg->pr_reg_nacl = NULL;
> -		kfree(pr_reg->pr_aptpl_buf);
>  		kmem_cache_free(t10_pr_reg_cache, pr_reg);
>  		return;
>  	}
> @@ -1341,7 +1332,6 @@ void core_scsi3_free_all_registrations(
>  	list_for_each_entry_safe(pr_reg, pr_reg_tmp, &pr_tmpl->aptpl_reg_list,
>  				pr_reg_aptpl_list) {
>  		list_del(&pr_reg->pr_reg_aptpl_list);
> -		kfree(pr_reg->pr_aptpl_buf);
>  		kmem_cache_free(t10_pr_reg_cache, pr_reg);
>  	}
>  	spin_unlock(&pr_tmpl->aptpl_reg_lock);
> @@ -1814,7 +1804,6 @@ out:
>  			kmem_cache_free(t10_pr_reg_cache, pr_reg_tmp);
>  		}
>  
> -		kfree(dest_pr_reg->pr_aptpl_buf);
>  		kmem_cache_free(t10_pr_reg_cache, dest_pr_reg);
>  
>  		if (dest_local_nexus)
> @@ -1840,8 +1829,6 @@ static int core_scsi3_update_aptpl_buf(
>  	int reg_count = 0;
>  	int ret = 0;
>  
> -	memset(buf, 0, pr_aptpl_buf_len);
> -
>  	spin_lock(&dev->dev_reservation_lock);
>  	spin_lock(&dev->t10_pr.registration_lock);
>  	/*
> @@ -1965,31 +1952,45 @@ static int __core_scsi3_write_aptpl_to_file(
>  	return ret ? -EIO : 0;
>  }
>  
> -static int
> -core_scsi3_update_and_write_aptpl(struct se_device *dev, unsigned char *in_buf,
> -		u32 in_pr_aptpl_buf_len)
> +/*
> + * Clear the APTPL metadata if APTPL has been disabled, otherwise
> + * write out the updated metadata to struct file for this SCSI device.
> + */
> +static int core_scsi3_update_and_write_aptpl(struct se_device *dev, bool aptpl)
>  {
> -	unsigned char null_buf[64], *buf;
> -	int ret;
> +	int ret = 0;
>  
> -	/*
> -	 * Can be called with a NULL pointer from PROUT service action CLEAR
> -	 */
> -	if (!in_buf) {
> -		snprintf(null_buf, 64, "No Registrations or Reservations\n");
> -		buf = null_buf;
> +	if (!aptpl) {
> +		char *null_buf = "No Registrations or Reservations\n";
> +
> +		ret = __core_scsi3_write_aptpl_to_file(dev, null_buf);
> +		dev->t10_pr.pr_aptpl_active = 0;
> +		pr_debug("SPC-3 PR: Set APTPL Bit Deactivated\n");
>  	} else {
> -		ret = core_scsi3_update_aptpl_buf(dev, in_buf, in_pr_aptpl_buf_len);
> -		if (ret != 0)
> +		int ret;
> +		unsigned char *buf;
> +
> +		buf = kzalloc(PR_APTPL_BUF_LEN, GFP_KERNEL);
> +		if (!buf)
> +			return -ENOMEM;
> +
> +		ret = core_scsi3_update_aptpl_buf(dev, buf, PR_APTPL_BUF_LEN);
> +		if (ret < 0) {
> +			kfree(buf);
>  			return ret;
> -		buf = in_buf;
> +		}
> +
> +		ret = __core_scsi3_write_aptpl_to_file(dev, buf);
> +		if (ret != 0) {
> +			pr_err("SPC-3 PR: Could not update APTPL\n");
> +		} else {
> +			dev->t10_pr.pr_aptpl_active = 1;
> +			pr_debug("SPC-3 PR: Set APTPL Bit Activated\n");
> +		}
> +		kfree(buf);
>  	}
>  
> -	/*
> -	 * __core_scsi3_write_aptpl_to_file() will call strlen()
> -	 * on the passed buf to determine pr_aptpl_buf_len.
> -	 */
> -	return __core_scsi3_write_aptpl_to_file(dev, buf);
> +	return ret;
>  }
>  
>  static sense_reason_t
> @@ -2003,8 +2004,6 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key,
>  	struct se_portal_group *se_tpg;
>  	struct t10_pr_registration *pr_reg, *pr_reg_p, *pr_reg_tmp, *pr_reg_e;
>  	struct t10_reservation *pr_tmpl = &dev->t10_pr;
> -	/* Used for APTPL metadata w/ UNREGISTER */
> -	unsigned char *pr_aptpl_buf = NULL;
>  	unsigned char isid_buf[PR_REG_ISID_LEN], *isid_ptr = NULL;
>  	sense_reason_t ret = TCM_NO_SENSE;
>  	int pr_holder = 0, type;
> @@ -2066,31 +2065,8 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key,
>  			if (ret != 0)
>  				return ret;
>  		}
> -		/*
> -		 * Nothing left to do for the APTPL=0 case.
> -		 */
> -		if (!aptpl) {
> -			pr_tmpl->pr_aptpl_active = 0;
> -			core_scsi3_update_and_write_aptpl(cmd->se_dev, NULL, 0);
> -			pr_debug("SPC-3 PR: Set APTPL Bit Deactivated for"
> -					" REGISTER\n");
> -			return 0;
> -		}
> -		/*
> -		 * Locate the newly allocated local I_T Nexus *pr_reg, and
> -		 * update the APTPL metadata information using its
> -		 * preallocated *pr_reg->pr_aptpl_buf.
> -		 */
> -		pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev,
> -				se_sess->se_node_acl, se_sess);
>  
> -		if (core_scsi3_update_and_write_aptpl(cmd->se_dev,
> -				pr_reg->pr_aptpl_buf, PR_APTPL_BUF_LEN)) {
> -			pr_tmpl->pr_aptpl_active = 1;
> -			pr_debug("SPC-3 PR: Set APTPL Bit Activated for REGISTER\n");
> -		}
> -
> -		goto out_put_pr_reg;
> +		return core_scsi3_update_and_write_aptpl(dev, aptpl);
>  	}
>  
>  	/*
> @@ -2131,28 +2107,30 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key,
>  	}
>  
>  	/*
> -	 * Allocate APTPL metadata buffer used for UNREGISTER ops
> +	 * sa_res_key=1 Change Reservation Key for registered I_T Nexus.
>  	 */
> -	if (aptpl) {
> -		pr_aptpl_buf = kzalloc(PR_APTPL_BUF_LEN, GFP_KERNEL);
> -		if (!pr_aptpl_buf) {
> -			pr_err("Unable to allocate"
> -				" pr_aptpl_buf\n");
> -			ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
> -			goto out_put_pr_reg;
> -		}
> -	}
> +	if (sa_res_key) {
> +		/*
> +		 * Increment PRgeneration counter for struct se_device"
> +		 * upon a successful REGISTER, see spc4r17 section 6.3.2
> +		 * READ_KEYS service action.
> +		 */
> +		pr_reg->pr_res_generation = core_scsi3_pr_generation(cmd->se_dev);
> +		pr_reg->pr_res_key = sa_res_key;
> +		pr_debug("SPC-3 PR [%s] REGISTER%s: Changed Reservation"
> +			 " Key for %s to: 0x%016Lx PRgeneration:"
> +			 " 0x%08x\n", cmd->se_tfo->get_fabric_name(),
> +			 (register_type == REGISTER_AND_IGNORE_EXISTING_KEY) ? "_AND_IGNORE_EXISTING_KEY" : "",
> +			 pr_reg->pr_reg_nacl->initiatorname,
> +			 pr_reg->pr_res_key, pr_reg->pr_res_generation);
>  
> -	/*
> -	 * sa_res_key=0 Unregister Reservation Key for registered I_T
> -	 * Nexus sa_res_key=1 Change Reservation Key for registered I_T
> -	 * Nexus.
> -	 */
> -	if (!sa_res_key) {
> +	} else {
> +		/*
> +		 * sa_res_key=0 Unregister Reservation Key for registered I_T Nexus.
> +		 */
>  		pr_holder = core_scsi3_check_implict_release(
>  				cmd->se_dev, pr_reg);
>  		if (pr_holder < 0) {
> -			kfree(pr_aptpl_buf);
>  			ret = TCM_RESERVATION_CONFLICT;
>  			goto out_put_pr_reg;
>  		}
> @@ -2212,57 +2190,12 @@ core_scsi3_emulate_pro_register(struct se_cmd *cmd, u64 res_key, u64 sa_res_key,
>  					ASCQ_2AH_RESERVATIONS_RELEASED);
>  			}
>  		}
> -		spin_unlock(&pr_tmpl->registration_lock);
> -
> -		if (!aptpl) {
> -			pr_tmpl->pr_aptpl_active = 0;
> -			core_scsi3_update_and_write_aptpl(dev, NULL, 0);
> -			pr_debug("SPC-3 PR: Set APTPL Bit Deactivated"
> -					" for UNREGISTER\n");
> -			return 0;
> -		}
> -
> -		if (!core_scsi3_update_and_write_aptpl(dev, pr_aptpl_buf, PR_APTPL_BUF_LEN)) {
> -			pr_tmpl->pr_aptpl_active = 1;
> -			pr_debug("SPC-3 PR: Set APTPL Bit Activated"
> -					" for UNREGISTER\n");
> -		}
> -
> -		goto out_free_aptpl_buf;
> -	}
>  
> -	/*
> -	 * Increment PRgeneration counter for struct se_device"
> -	 * upon a successful REGISTER, see spc4r17 section 6.3.2
> -	 * READ_KEYS service action.
> -	 */
> -	pr_reg->pr_res_generation = core_scsi3_pr_generation(cmd->se_dev);
> -	pr_reg->pr_res_key = sa_res_key;
> -	pr_debug("SPC-3 PR [%s] REGISTER%s: Changed Reservation"
> -		" Key for %s to: 0x%016Lx PRgeneration:"
> -		" 0x%08x\n", cmd->se_tfo->get_fabric_name(),
> -		(register_type == REGISTER_AND_IGNORE_EXISTING_KEY) ? "_AND_IGNORE_EXISTING_KEY" : "",
> -		pr_reg->pr_reg_nacl->initiatorname,
> -		pr_reg->pr_res_key, pr_reg->pr_res_generation);
> -
> -	if (!aptpl) {
> -		pr_tmpl->pr_aptpl_active = 0;
> -		core_scsi3_update_and_write_aptpl(dev, NULL, 0);
> -		pr_debug("SPC-3 PR: Set APTPL Bit Deactivated"
> -				" for REGISTER\n");
> -		ret = 0;
> -		goto out_put_pr_reg;
> +		spin_unlock(&pr_tmpl->registration_lock);
>  	}
>  
> -	if (!core_scsi3_update_and_write_aptpl(dev, pr_aptpl_buf, PR_APTPL_BUF_LEN)) {
> -		pr_tmpl->pr_aptpl_active = 1;
> -		pr_debug("SPC-3 PR: Set APTPL Bit Activated"
> -			" for REGISTER\n");
> -	}
> +	ret = core_scsi3_update_and_write_aptpl(dev, aptpl);
>  
> -out_free_aptpl_buf:
> -	kfree(pr_aptpl_buf);
> -	ret = 0;
>  out_put_pr_reg:
>  	core_scsi3_put_pr_reg(pr_reg);
>  	return ret;
> @@ -2437,13 +2370,8 @@ core_scsi3_pro_reserve(struct se_cmd *cmd, int type, int scope, u64 res_key)
>  			i_buf);
>  	spin_unlock(&dev->dev_reservation_lock);
>  
> -	if (pr_tmpl->pr_aptpl_active) {
> -		if (!core_scsi3_update_and_write_aptpl(cmd->se_dev,
> -				pr_reg->pr_aptpl_buf, PR_APTPL_BUF_LEN)) {
> -			pr_debug("SPC-3 PR: Updated APTPL metadata"
> -					" for RESERVE\n");
> -		}
> -	}
> +	if (pr_tmpl->pr_aptpl_active)
> +		core_scsi3_update_and_write_aptpl(cmd->se_dev, true);
>  
>  	ret = 0;
>  out_put_pr_reg:
> @@ -2657,12 +2585,9 @@ core_scsi3_emulate_pro_release(struct se_cmd *cmd, int type, int scope,
>  	spin_unlock(&pr_tmpl->registration_lock);
>  
>  write_aptpl:
> -	if (pr_tmpl->pr_aptpl_active) {
> -		if (!core_scsi3_update_and_write_aptpl(cmd->se_dev,
> -			pr_reg->pr_aptpl_buf, PR_APTPL_BUF_LEN)) {
> -			pr_debug("SPC-3 PR: Updated APTPL metadata for RELEASE\n");
> -		}
> -	}
> +	if (pr_tmpl->pr_aptpl_active)
> +		core_scsi3_update_and_write_aptpl(cmd->se_dev, true);
> +
>  out_put_pr_reg:
>  	core_scsi3_put_pr_reg(pr_reg);
>  	return ret;
> @@ -2746,11 +2671,7 @@ core_scsi3_emulate_pro_clear(struct se_cmd *cmd, u64 res_key)
>  	pr_debug("SPC-3 PR [%s] Service Action: CLEAR complete\n",
>  		cmd->se_tfo->get_fabric_name());
>  
> -	if (pr_tmpl->pr_aptpl_active) {
> -		core_scsi3_update_and_write_aptpl(cmd->se_dev, NULL, 0);
> -		pr_debug("SPC-3 PR: Updated APTPL metadata"
> -				" for CLEAR\n");
> -	}
> +	core_scsi3_update_and_write_aptpl(cmd->se_dev, false);
>  
>  	core_scsi3_pr_generation(dev);
>  	return 0;
> @@ -2822,7 +2743,6 @@ static void core_scsi3_release_preempt_and_abort(
>  
>  		pr_reg->pr_reg_deve = NULL;
>  		pr_reg->pr_reg_nacl = NULL;
> -		kfree(pr_reg->pr_aptpl_buf);
>  		kmem_cache_free(t10_pr_reg_cache, pr_reg);
>  	}
>  }
> @@ -2984,14 +2904,8 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key,
>  		}
>  		spin_unlock(&dev->dev_reservation_lock);
>  
> -		if (pr_tmpl->pr_aptpl_active) {
> -			if (!core_scsi3_update_and_write_aptpl(cmd->se_dev,
> -					pr_reg_n->pr_aptpl_buf,	PR_APTPL_BUF_LEN)) {
> -				pr_debug("SPC-3 PR: Updated APTPL"
> -					" metadata for  PREEMPT%s\n", (preempt_type == PREEMPT_AND_ABORT) ?
> -					"_AND_ABORT" : "");
> -			}
> -		}
> +		if (pr_tmpl->pr_aptpl_active)
> +			core_scsi3_update_and_write_aptpl(cmd->se_dev, true);
>  
>  		core_scsi3_put_pr_reg(pr_reg_n);
>  		core_scsi3_pr_generation(cmd->se_dev);
> @@ -3119,13 +3033,8 @@ core_scsi3_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_key,
>  						pr_reg_n);
>  	}
>  
> -	if (pr_tmpl->pr_aptpl_active) {
> -		if (!core_scsi3_update_and_write_aptpl(cmd->se_dev,
> -				pr_reg_n->pr_aptpl_buf, PR_APTPL_BUF_LEN)) {
> -			pr_debug("SPC-3 PR: Updated APTPL metadata for PREEMPT"
> -				"%s\n", (preempt_type == PREEMPT_AND_ABORT) ? "_AND_ABORT" : "");
> -		}
> -	}
> +	if (pr_tmpl->pr_aptpl_active)
> +		core_scsi3_update_and_write_aptpl(cmd->se_dev, true);
>  
>  	core_scsi3_put_pr_reg(pr_reg_n);
>  	core_scsi3_pr_generation(cmd->se_dev);
> @@ -3552,23 +3461,7 @@ after_iport_check:
>  	} else
>  		core_scsi3_put_pr_reg(pr_reg);
>  
> -	/*
> -	 * Clear the APTPL metadata if APTPL has been disabled, otherwise
> -	 * write out the updated metadata to struct file for this SCSI device.
> -	 */
> -	if (!aptpl) {
> -		pr_tmpl->pr_aptpl_active = 0;
> -		core_scsi3_update_and_write_aptpl(cmd->se_dev, NULL, 0);
> -		pr_debug("SPC-3 PR: Set APTPL Bit Deactivated for"
> -				" REGISTER_AND_MOVE\n");
> -	} else {
> -		pr_tmpl->pr_aptpl_active = 1;
> -		if (!core_scsi3_update_and_write_aptpl(cmd->se_dev,
> -				dest_pr_reg->pr_aptpl_buf, PR_APTPL_BUF_LEN)) {
> -			pr_debug("SPC-3 PR: Set APTPL Bit Activated for"
> -					" REGISTER_AND_MOVE\n");
> -		}
> -	}
> +	core_scsi3_update_and_write_aptpl(cmd->se_dev, aptpl);
>  
>  	transport_kunmap_data_sg(cmd);
>  
> diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
> index dca2e3c..3314c4b 100644
> --- a/include/target/target_core_base.h
> +++ b/include/target/target_core_base.h
> @@ -339,8 +339,6 @@ struct t10_pr_registration {
>  	/* Used during APTPL metadata reading */
>  #define PR_APTPL_MAX_TPORT_LEN			256
>  	unsigned char pr_tport[PR_APTPL_MAX_TPORT_LEN];
> -	/* For writing out live meta data */
> -	unsigned char *pr_aptpl_buf;
>  	u16 pr_aptpl_rpti;
>  	u16 pr_reg_tpgt;
>  	/* Reservation effects all target ports */


--
To unsubscribe from this list: send the line "unsubscribe target-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux SCSI]     [Kernel Newbies]     [Linux SCSI Target Infrastructure]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Device Mapper]

  Powered by Linux