109 error: |
110 error: |
110 if ((err = fuse_reply_err(req, err))) |
111 if ((err = fuse_reply_err(req, err))) |
111 EWARNING(err, "fuse_reply_err"); |
112 EWARNING(err, "fuse_reply_err"); |
112 } |
113 } |
113 |
114 |
114 void simple_readdir (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi) { |
115 static void simple_readdir (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi) { |
115 struct simple_fs *fs = fuse_req_userdata(req); |
116 struct simple_fs *fs = fuse_req_userdata(req); |
116 const struct simple_node *dir_node, *node; |
117 const struct simple_node *dir_node, *node; |
117 struct dirbuf buf; |
118 struct dirbuf buf; |
118 int err; |
119 int err; |
119 |
120 |
164 error: |
165 error: |
165 if ((err = fuse_reply_err(req, err))) |
166 if ((err = fuse_reply_err(req, err))) |
166 EWARNING(err, "fuse_reply_err"); |
167 EWARNING(err, "fuse_reply_err"); |
167 } |
168 } |
168 |
169 |
|
170 static void simple_read (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi) { |
|
171 struct simple_fs *fs = fuse_req_userdata(req); |
|
172 const struct simple_node *node; |
|
173 int err ; |
|
174 |
|
175 // fi is unused |
|
176 (void) fi; |
|
177 |
|
178 INFO("[simple.read] ino=%lu, size=%zu, off=%zu, fi=%p", ino, size, off, fi); |
|
179 |
|
180 // look up the inode |
|
181 if ((node = _simple_get_ino(fs, ino)) == NULL) |
|
182 EERROR(err = EINVAL, "bad inode"); |
|
183 |
|
184 // check that it's a dir |
|
185 if (node->mode_type != S_IFREG) |
|
186 EERROR(err = (node->mode_type == S_IFDIR ? EISDIR : EINVAL), "bad mode"); |
|
187 |
|
188 // seek past EOF? |
|
189 if (off >= strlen(node->data)) { |
|
190 // offset is out-of-file, so return EOF |
|
191 if ((err = fuse_reply_buf(req, NULL, 0))) |
|
192 EERROR(err, "fuse_reply_buf size=0"); |
|
193 |
|
194 } else { |
|
195 // reply with the requested file data |
|
196 if ((err = fuse_reply_buf(req, node->data + off, MIN(strlen(node->data) - off, size)))) |
|
197 EERROR(err, "fuse_reply_buf buf=%p + %zu, size=MIN(%zu, %zu)", node->data, off, strlen(node->data) - off, size); |
|
198 } |
|
199 |
|
200 // success |
|
201 return; |
|
202 |
|
203 error: |
|
204 if ((err = fuse_reply_err(req, err))) |
|
205 EWARNING(err, "fuse_reply_err"); |
|
206 } |
|
207 |
|
208 |
169 /* |
209 /* |
170 * Define our fuse_lowlevel_ops struct. |
210 * Define our fuse_lowlevel_ops struct. |
171 */ |
211 */ |
172 static struct fuse_lowlevel_ops simple_ops = { |
212 static struct fuse_lowlevel_ops simple_ops = { |
173 .lookup = simple_lookup, |
213 .lookup = simple_lookup, |
174 |
214 |
175 .getattr = simple_getattr, |
215 .getattr = simple_getattr, |
176 |
216 |
177 .readdir = simple_readdir, |
217 .readdir = simple_readdir, |
|
218 |
|
219 .read = simple_read, |
178 }; |
220 }; |
179 |
221 |
180 struct fuse_lowlevel_ops *simple_init () { |
222 struct fuse_lowlevel_ops *simple_init () { |
181 return &simple_ops; |
223 return &simple_ops; |
182 } |
224 } |