diff options
Diffstat (limited to 'src/fuse/read.c')
-rw-r--r-- | src/fuse/read.c | 59 |
1 files changed, 52 insertions, 7 deletions
diff --git a/src/fuse/read.c b/src/fuse/read.c index d6774e0..de950a8 100644 --- a/src/fuse/read.c +++ b/src/fuse/read.c | |||
@@ -52,15 +52,22 @@ gn_read (const char *path, char *buf, size_t size, off_t offset, | |||
52 | struct GNUNET_FUSE_PathInfo *path_info; | 52 | struct GNUNET_FUSE_PathInfo *path_info; |
53 | uint64_t fsize; | 53 | uint64_t fsize; |
54 | struct GNUNET_DISK_FileHandle *fh; | 54 | struct GNUNET_DISK_FileHandle *fh; |
55 | int eno; | ||
55 | 56 | ||
56 | path_info = GNUNET_FUSE_path_info_get (path); | 57 | path_info = GNUNET_FUSE_path_info_get (path, &eno); |
57 | if (NULL == path_info) | 58 | if (NULL == path_info) |
59 | return - eno; | ||
60 | fsize = GNUNET_FS_uri_chk_get_file_size (path_info->uri); | ||
61 | if (offset > fsize) | ||
58 | { | 62 | { |
59 | /* FIXME: we might need to check which of the ancestors | 63 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
60 | exist and possibly download ancestral directories, | 64 | "No data available at offset %llu of file `%s'\n", |
61 | instead of directly giving up here... */ | 65 | (unsigned long long) offset, |
62 | return - ENOENT; | 66 | path); |
63 | } | 67 | return 0; |
68 | } | ||
69 | if (offset + size > fsize) | ||
70 | size = fsize - offset; | ||
64 | if (NULL == path_info->tmpfile) | 71 | if (NULL == path_info->tmpfile) |
65 | { | 72 | { |
66 | /* store to temporary file */ | 73 | /* store to temporary file */ |
@@ -76,8 +83,46 @@ gn_read (const char *path, char *buf, size_t size, off_t offset, | |||
76 | return - EIO; /* low level IO error */ | 83 | return - EIO; /* low level IO error */ |
77 | } | 84 | } |
78 | } | 85 | } |
86 | else | ||
87 | { | ||
88 | if ( (offset < path_info->download_start) || | ||
89 | (size + offset > path_info->download_end) ) | ||
90 | { | ||
91 | /* need to download some more... */ | ||
92 | if (GNUNET_OK != GNUNET_FUSE_download_file (path_info, | ||
93 | offset, | ||
94 | size)) | ||
95 | { | ||
96 | UNLINK (path_info->tmpfile); | ||
97 | GNUNET_free (path_info->tmpfile); | ||
98 | path_info->tmpfile = NULL; | ||
99 | GNUNET_FUSE_path_info_done (path_info); | ||
100 | return - EIO; /* low level IO error */ | ||
101 | } | ||
102 | } | ||
103 | } | ||
104 | /* combine ranges */ | ||
105 | if (path_info->download_start == path_info->download_end) | ||
106 | { | ||
107 | /* first range */ | ||
108 | path_info->download_start = offset; | ||
109 | path_info->download_end = offset + size; | ||
110 | } | ||
111 | else | ||
112 | { | ||
113 | /* only combine ranges if the resulting range would | ||
114 | be contiguous... */ | ||
115 | if ( (offset >= path_info->download_start) && | ||
116 | (offset <= path_info->download_end) && | ||
117 | (offset + size > path_info->download_end) ) | ||
118 | path_info->download_end = offset + size; | ||
119 | if ( (offset + size >= path_info->download_start) && | ||
120 | (offset + size <= path_info->download_end) && | ||
121 | (offset < path_info->download_start) ) | ||
122 | path_info->download_start = offset; | ||
123 | } | ||
124 | |||
79 | 125 | ||
80 | fsize = GNUNET_FS_uri_chk_get_file_size (path_info->uri); | ||
81 | fh = GNUNET_DISK_file_open (path_info->tmpfile, | 126 | fh = GNUNET_DISK_file_open (path_info->tmpfile, |
82 | GNUNET_DISK_OPEN_READ, | 127 | GNUNET_DISK_OPEN_READ, |
83 | GNUNET_DISK_PERM_NONE); | 128 | GNUNET_DISK_PERM_NONE); |