aboutsummaryrefslogtreecommitdiff
path: root/src/fuse/read.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fuse/read.c')
-rw-r--r--src/fuse/read.c59
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);