[sheepdog] [PATCH v1 1/4] sheep/http: add nolock version for some functions

Liu Yuan namei.unix at gmail.com
Fri Feb 21 08:27:05 CET 2014


On Fri, Feb 21, 2014 at 02:47:30PM +0800, Robin Dong wrote:
> From: Robin Dong <sanbai at taobao.com>
> 
> Add nolock version for onode_create(), onode_lookup(), onode_delete_object()
> ---
>  sheep/http/kv.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++---------
>  1 file changed, 66 insertions(+), 12 deletions(-)
> 
> diff --git a/sheep/http/kv.c b/sheep/http/kv.c
> index ac9decb..4ac69fc 100644
> --- a/sheep/http/kv.c
> +++ b/sheep/http/kv.c
> @@ -779,7 +779,7 @@ out:
>  	return ret;
>  }
>  
> -static int onode_create(struct kv_onode *onode, uint32_t bucket_vid)
> +static int onode_create_nolock(struct kv_onode *onode, uint32_t bucket_vid)
>  {
>  	struct sd_inode *inode = xmalloc(sizeof(struct sd_inode));
>  	uint32_t tmp_vid, idx;
> @@ -787,7 +787,6 @@ static int onode_create(struct kv_onode *onode, uint32_t bucket_vid)
>  	int ret;
>  	bool create = true;
>  
> -	sys->cdrv->lock(bucket_vid);
>  	ret = sd_read_object(vid_to_vdi_oid(bucket_vid), (char *)inode,
>  			       sizeof(*inode), 0);
>  	if (ret != SD_RES_SUCCESS) {
> @@ -822,21 +821,33 @@ create:
>  	ret = onode_do_create(onode, inode, idx, create);
>  out:
>  	free(inode);
> +	return ret;
> +}
> +
> +static int onode_create(struct kv_onode *onode, uint32_t bucket_vid)
> +{
> +	int ret;
> +
> +	sys->cdrv->lock(bucket_vid);
> +	ret = onode_create_nolock(onode, bucket_vid);
>  	sys->cdrv->unlock(bucket_vid);
> +
>  	return ret;
>  }
>  
> -static int onode_free_data(struct kv_onode *onode)
> +static int onode_free_data(struct kv_onode *onode, int lock)
>  {
>  	uint32_t data_vid = onode->data_vid;
>  	int ret = SD_RES_SUCCESS;
>  
>  	/* it don't need to free data for inlined onode */
>  	if (!onode->inlined) {
> -		sys->cdrv->lock(data_vid);
> +		if (lock)
> +			sys->cdrv->lock(data_vid);
>  		ret = oalloc_free(data_vid, onode->o_extent[0].start,
>  				  onode->o_extent[0].count);
> -		sys->cdrv->unlock(data_vid);
> +		if (lock)
> +			sys->cdrv->unlock(data_vid);
>  		if (ret != SD_RES_SUCCESS)
>  			sd_err("failed to free %s", onode->name);
>  	}
> @@ -901,14 +912,14 @@ out:
>   *
>   * [ sheep, dog, wolve, '\0', fish, {unallocated}, tiger, ]
>   */
> -static int onode_lookup(struct kv_onode *onode, uint32_t ovid, const char *name)
> +static int onode_lookup_nolock(struct kv_onode *onode, uint32_t ovid,
> +			       const char *name)
>  {
>  	struct sd_inode *inode = xmalloc(sizeof(struct sd_inode));
>  	uint32_t tmp_vid, idx;
>  	uint64_t hval, i;
>  	int ret;
>  
> -	sys->cdrv->lock(ovid);
>  	ret = sd_read_object(vid_to_vdi_oid(ovid), (char *)inode,
>  			     sizeof(*inode), 0);
>  	if (ret != SD_RES_SUCCESS) {
> @@ -941,7 +952,17 @@ static int onode_lookup(struct kv_onode *onode, uint32_t ovid, const char *name)
>  	}
>  out:
>  	free(inode);
> +	return ret;
> +}
> +
> +static int onode_lookup(struct kv_onode *onode, uint32_t ovid, const char *name)
> +{
> +	int ret;
> +
> +	sys->cdrv->lock(ovid);
> +	ret = onode_lookup_nolock(onode, ovid, name);
>  	sys->cdrv->unlock(ovid);
> +
>  	return ret;
>  }
>  
> @@ -990,7 +1011,7 @@ static int onode_read_data(struct kv_onode *onode, struct http_request *req)
>   *
>   * XXX: GC the orphans
>   */
> -static int onode_delete(struct kv_onode *onode)
> +static int onode_delete(struct kv_onode *onode, int lock)
>  {
>  	char name[SD_MAX_OBJECT_NAME] = {};
>  	int ret;
> @@ -1001,7 +1022,7 @@ static int onode_delete(struct kv_onode *onode)
>  		return ret;
>  	}
>  
> -	ret = onode_free_data(onode);
> +	ret = onode_free_data(onode, lock);
>  	if (ret != SD_RES_SUCCESS)
>  		sd_err("failed to free data for %s", onode->name);
>  
> @@ -1057,14 +1078,14 @@ int kv_create_object(struct http_request *req, const char *account,
>  	ret = onode_create(onode, bucket_vid);
>  	if (ret != SD_RES_SUCCESS) {
>  		sd_err("failed to create onode for %s", name);
> -		onode_free_data(onode);
> +		onode_free_data(onode, 1);
>  		goto out;
>  	}
>  
>  	ret = bnode_update(account, bucket, req->data_length, true);
>  	if (ret != SD_RES_SUCCESS) {
>  		sd_err("failed to update bucket for %s", name);
> -		onode_delete(onode);
> +		onode_delete(onode, 1);
>  		goto out;
>  	}
>  out:
> @@ -1098,6 +1119,39 @@ out:
>  	return ret;
>  }
>  
> +static int kv_delete_object_nolock(const char *account, const char *bucket,
> +				   const char *name)
> +{
> +	char vdi_name[SD_MAX_VDI_LEN];
> +	uint32_t bucket_vid;
> +	struct kv_onode *onode = NULL;
> +	int ret;
> +
> +	snprintf(vdi_name, SD_MAX_VDI_LEN, "%s/%s", account, bucket);
> +	ret = sd_lookup_vdi(vdi_name, &bucket_vid);
> +	if (ret != SD_RES_SUCCESS)
> +		return ret;
> +
> +	onode = xzalloc(sizeof(*onode));
> +	ret = onode_lookup_nolock(onode, bucket_vid, name);
> +	if (ret != SD_RES_SUCCESS)
> +		goto out;
> +
> +	ret = onode_delete(onode, 0);
> +	if (ret != SD_RES_SUCCESS) {
> +		sd_err("failed to delete bnode for %s", name);
> +		goto out;
> +	}
> +	ret = bnode_update(account, bucket, onode->size, false);
> +	if (ret != SD_RES_SUCCESS) {
> +		sd_err("failed to update bnode for %s", name);
> +		goto out;
> +	}
> +out:
> +	free(onode);
> +	return ret;
> +}
> +
>  int kv_delete_object(const char *account, const char *bucket, const char *name)

kv_delete_object() should be implemented as

kv_delete_object()
{
	lock();
	kv_delete_object_nolock();
	unlock();
}

Thanks
Yuan



More information about the sheepdog mailing list