[sheepdog] [PATCH v1 1/2] sheepfs/http: read next cache if data of current cache has been read out

Liu Yuan namei.unix at gmail.com
Mon Mar 24 07:16:14 CET 2014


On Fri, Mar 21, 2014 at 01:13:58PM +0800, Robin Dong wrote:
> From: Robin Dong <sanbai at taobao.com>
> 
> When we use command 'tar' to extract a tar-file in http interface of sheepfs,
> it report error and quit. The reason is that if a read operation has almost
> reach the end of current cache, it will only return the size which has not
> been read in CURRENT CACHE at present.
> For example, if a read operation want to read 1MB and it already reach the
> offset of (63MB + 500K) in current cache, the read() will return 524K even
> the file has more data to read. The tool of 'tar' read 10KB every time, so if
> its read() return size below 10KB, it will think the file is end and quit
> which cause problems.
> 
> The solution is simple: if current cache has almost been read out, try to
> read data of next cache.
> 
> Signed-off-by: Robin Dong <sanbai at taobao.com>
> ---
>  sheepfs/http.c | 32 +++++++++++++++++++++++---------
>  1 file changed, 23 insertions(+), 9 deletions(-)
> 
> diff --git a/sheepfs/http.c b/sheepfs/http.c
> index 630129c..3732db3 100644
> --- a/sheepfs/http.c
> +++ b/sheepfs/http.c
> @@ -324,6 +324,15 @@ static void *fetch_thread_run(void *arg)
>  	return NULL;
>  }
>  
> +static int object_wait_cache(struct cache_handle *ch)
> +{
> +	sem_wait(&ch->ready_sem);
> +	swap_cache(ch);
> +	ch->fetch_offset = ch->ready->offset + ch->ready->size;
> +	sem_post(&ch->prepare_sem);
> +	return  ch->ready->size;
> +}
> +
>  int object_read(const char *path, char *buf, size_t size, off_t offset,
>  		struct fuse_file_info *fi)
>  {
> @@ -351,19 +360,24 @@ int object_read(const char *path, char *buf, size_t size, off_t offset,
>  			else
>  				ret = (cache->offset + cache->size) - offset;
>  			memcpy(buf, cache->mem + (offset - cache->offset), ret);
> +			/* read next cache if not fulfill the 'size' */
> +			if (ret < size && object_wait_cache(ch) > 0) {
> +				int extra_read;
> +				buf += ret;
> +				offset += ret;
> +				cache = ch->ready;
> +				extra_read = min(cache->size, size - ret);
> +				memcpy(buf, cache->mem +
> +				       (offset - cache->offset), extra_read);
> +				ret += extra_read;
> +			}
>  			break;
>  		} else if (offset >= ch->obj_size) {
>  			ret = 0;
>  			break;
> -		} else {
> -			sem_wait(&ch->ready_sem);
> -			swap_cache(ch);
> -			ch->fetch_offset = ch->ready->offset + ch->ready->size;
> -			sem_post(&ch->prepare_sem);
> -			if (ch->ready->size == 0) {
> -				ret = 0;
> -				break;
> -			}
> +		} else if (!object_wait_cache(ch)) {
> +			ret = 0;
> +			break;
>  		}
>  	}
>  out:
> -- 
> 1.7.12.4
> 
> -- 
> sheepdog mailing list
> sheepdog at lists.wpkg.org
> http://lists.wpkg.org/mailman/listinfo/sheepdog

Applied thanks

Yuan



More information about the sheepdog mailing list