[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