1 // netfs.cpp
2
3 #include <new>
4
5 #include <KernelExport.h>
6 #include <fsproto.h>
7
8 #include "DebugSupport.h"
9 #include "Node.h"
10 #include "ObjectTracker.h"
11 #include "QueryManager.h"
12 #include "RootVolume.h"
13 #include "VolumeManager.h"
14
15 // #pragma mark -
16 // #pragma mark ----- prototypes -----
17
18 extern "C" {
19
20 // fs
21 static int netfs_mount(nspace_id nsid, const char *device, ulong flags,
22 void *parameters, size_t len, void **data, vnode_id *rootID);
23 static int netfs_unmount(void *ns);
24 //static int netfs_sync(void *ns);
25 static int netfs_read_fs_stat(void *ns, struct fs_info *info);
26 //static int netfs_write_fs_stat(void *ns, struct fs_info *info, long mask);
27
28 // vnodes
29 static int netfs_read_vnode(void *ns, vnode_id vnid, char reenter,
30 void **node);
31 static int netfs_write_vnode(void *ns, void *node, char reenter);
32 static int netfs_remove_vnode(void *ns, void *node, char reenter);
33
34 // nodes
35 //static int netfs_fsync(void *ns, void *node);
36 static int netfs_read_stat(void *ns, void *node, struct stat *st);
37 static int netfs_write_stat(void *ns, void *node, struct stat *st,
38 long mask);
39 static int netfs_access(void *ns, void *node, int mode);
40
41 // files
42 static int netfs_create(void *ns, void *dir, const char *name,
43 int openMode, int mode, vnode_id *vnid, void **cookie);
44 static int netfs_open(void *ns, void *node, int openMode, void **cookie);
45 static int netfs_close(void *ns, void *node, void *cookie);
46 static int netfs_free_cookie(void *ns, void *node, void *cookie);
47 static int netfs_read(void *ns, void *node, void *cookie, off_t pos,
48 void *buffer, size_t *bufferSize);
49 static int netfs_write(void *ns, void *node, void *cookie, off_t pos,
50 const void *buffer, size_t *bufferSize);
51 static int netfs_ioctl(void *ns, void *node, void *cookie, int cmd,
52 void *buffer, size_t bufferSize);
53 //static int netfs_setflags(void *ns, void *node, void *cookie, int flags);
54
55 // hard links / symlinks
56 static int netfs_link(void *ns, void *dir, const char *name, void *node);
57 static int netfs_unlink(void *ns, void *dir, const char *name);
58 static int netfs_symlink(void *ns, void *dir, const char *name,
59 const char *path);
60 static int netfs_read_link(void *ns, void *node, char *buffer,
61 size_t *bufferSize);
62 static int netfs_rename(void *ns, void *oldDir, const char *oldName,
63 void *newDir, const char *newName);
64
65 // directories
66 static int netfs_mkdir(void *ns, void *dir, const char *name, int mode);
67 static int netfs_rmdir(void *ns, void *dir, const char *name);
68 static int netfs_open_dir(void *ns, void *node, void **cookie);
69 static int netfs_close_dir(void *ns, void *node, void *cookie);
70 static int netfs_free_dir_cookie(void *ns, void *node, void *cookie);
71 static int netfs_read_dir(void *ns, void *node, void *cookie,
72 long *count, struct dirent *buffer, size_t bufferSize);
73 static int netfs_rewind_dir(void *ns, void *node, void *cookie);
74 static int netfs_walk(void *ns, void *dir, const char *entryName,
75 char **resolvedPath, vnode_id *vnid);
76
77 // attributes
78 static int netfs_open_attrdir(void *ns, void *node, void **cookie);
79 static int netfs_close_attrdir(void *ns, void *node, void *cookie);
80 static int netfs_free_attrdir_cookie(void *ns, void *node, void *cookie);
81 static int netfs_read_attrdir(void *ns, void *node, void *cookie,
82 long *count, struct dirent *buffer, size_t bufferSize);
83 static int netfs_read_attr(void *ns, void *node, const char *name,
84 int type, void *buffer, size_t *bufferSize, off_t pos);
85 static int netfs_rewind_attrdir(void *ns, void *node, void *cookie);
86 static int netfs_write_attr(void *ns, void *node, const char *name,
87 int type, const void *buffer, size_t *bufferSize, off_t pos);
88 static int netfs_remove_attr(void *ns, void *node, const char *name);
89 static int netfs_rename_attr(void *ns, void *node, const char *oldName,
90 const char *newName);
91 static int netfs_stat_attr(void *ns, void *node, const char *name,
92 struct attr_info *attrInfo);
93
94 // queries
95 static int netfs_open_query(void *ns, const char *queryString, ulong flags,
96 port_id port, long token, void **cookie);
97 static int netfs_close_query(void *ns, void *cookie);
98 static int netfs_free_query_cookie(void *ns, void *node, void *cookie);
99 static int netfs_read_query(void *ns, void *cookie, long *count,
100 struct dirent *buffer, size_t bufferSize);
101
102 } // extern "C"
103
104 /* vnode_ops struct. Fill this in to tell the kernel how to call
105 functions in your driver.
106 */
107 vnode_ops fs_entry = {
108 &netfs_read_vnode, // read_vnode
109 &netfs_write_vnode, // write_vnode
110 &netfs_remove_vnode, // remove_vnode
111 NULL, // secure_vnode (not needed)
112 &netfs_walk, // walk
113 &netfs_access, // access
114 &netfs_create, // create
115 &netfs_mkdir, // mkdir
116 &netfs_symlink, // symlink
117 &netfs_link, // link
118 &netfs_rename, // rename
119 &netfs_unlink, // unlink
120 &netfs_rmdir, // rmdir
121 &netfs_read_link, // readlink
122 &netfs_open_dir, // opendir
123 &netfs_close_dir, // closedir
124 &netfs_free_dir_cookie, // free_dircookie
125 &netfs_rewind_dir, // rewinddir
126 &netfs_read_dir, // readdir
127 &netfs_open, // open file
128 &netfs_close, // close file
129 &netfs_free_cookie, // free cookie
130 &netfs_read, // read file
131 &netfs_write, // write file
132 NULL, // readv
133 NULL, // writev
134 &netfs_ioctl, // ioctl
135 NULL, // setflags file
136 &netfs_read_stat, // read stat
137 &netfs_write_stat, // write stat
138 NULL, // fsync
139 NULL, // initialize
140 &netfs_mount, // mount
141 &netfs_unmount, // unmount
142 NULL, // sync
143 &netfs_read_fs_stat, // read fs stat
144 NULL, // write fs stat
145 NULL, // select
146 NULL, // deselect
147
148 NULL, // open index dir
149 NULL, // close index dir
150 NULL, // free index dir cookie
151 NULL, // rewind index dir
152 NULL, // read index dir
153 NULL, // create index
154 NULL, // remove index
155 NULL, // rename index
156 NULL, // stat index
157
158 &netfs_open_attrdir, // open attr dir
159 &netfs_close_attrdir, // close attr dir
160 &netfs_free_attrdir_cookie, // free attr dir cookie
161 &netfs_rewind_attrdir, // rewind attr dir
162 &netfs_read_attrdir, // read attr dir
163 &netfs_write_attr, // write attr
164 &netfs_read_attr, // read attr
165 &netfs_remove_attr, // remove attr
166 &netfs_rename_attr, // rename attr
167 &netfs_stat_attr, // stat attr
168
169 &netfs_open_query, // open query
170 &netfs_close_query, // close query
171 &netfs_free_query_cookie, // free query cookie
172 &netfs_read_query, // read query
173 };
174
175 int32 api_version = B_CUR_FS_API_VERSION;
176
177 // #pragma mark -
178 // #pragma mark ----- fs -----
179
180 // netfs_mount
181 static
182 int
netfs_mount(nspace_id nsid,const char * device,ulong flags,void * parameters,size_t len,void ** data,vnode_id * rootID)183 netfs_mount(nspace_id nsid, const char *device, ulong flags,
184 void *parameters, size_t len, void **data, vnode_id *rootID)
185 {
186 status_t error = B_OK;
187 init_debugging();
188
189 #ifdef DEBUG_OBJECT_TRACKING
190 ObjectTracker::InitDefault();
191 #endif
192
193 // create and init the volume manager
194 VolumeManager* volumeManager = new(std::nothrow) VolumeManager(nsid, flags);
195 Volume* rootVolume = NULL;
196 if (volumeManager) {
197 error = volumeManager->MountRootVolume(device,
198 (const char*)parameters, len, &rootVolume);
199 if (error != B_OK) {
200 delete volumeManager;
201 volumeManager = NULL;
202 }
203 } else
204 error = B_NO_MEMORY;
205 VolumePutter _(rootVolume);
206
207 // set results
208 if (error == B_OK) {
209 *data = volumeManager;
210 *rootID = rootVolume->GetRootID();
211 } else {
212 #ifdef DEBUG_OBJECT_TRACKING
213 ObjectTracker::ExitDefault();
214 #endif
215 exit_debugging();
216 }
217 return error;
218 }
219
220 // netfs_unmount
221 static
222 int
netfs_unmount(void * ns)223 netfs_unmount(void *ns)
224 {
225 VolumeManager* volumeManager = (VolumeManager*)ns;
226
227 PRINT("netfs_unmount()\n");
228
229 volumeManager->UnmountRootVolume();
230 delete volumeManager;
231
232 #ifdef DEBUG_OBJECT_TRACKING
233 ObjectTracker::ExitDefault();
234 #endif
235
236 PRINT("netfs_unmount() done\n");
237
238 exit_debugging();
239 return B_OK;
240 }
241
242 #if 0 // not used
243
244 // netfs_sync
245 static
246 int
247 netfs_sync(void *ns)
248 {
249 VolumeManager* volumeManager = (VolumeManager*)ns;
250 Volume* volume = volumeManager->GetRootVolume();
251 VolumePutter _(volume);
252
253 PRINT("netfs_sync(%p)\n", ns);
254
255 status_t error = B_BAD_VALUE;
256 if (volume)
257 error = volume->Sync();
258
259 PRINT("netfs_sync() done: %" B_PRIx32 " \n", error);
260
261 return error;
262 }
263
264 #endif
265
266 // netfs_read_fs_stat
267 static
268 int
netfs_read_fs_stat(void * ns,struct fs_info * info)269 netfs_read_fs_stat(void *ns, struct fs_info *info)
270 {
271 VolumeManager* volumeManager = (VolumeManager*)ns;
272 Volume* volume = volumeManager->GetRootVolume();
273 VolumePutter _(volume);
274
275 PRINT("netfs_read_fs_stat(%p, %p)\n", ns, info);
276
277 status_t error = B_BAD_VALUE;
278 if (volume)
279 error = volume->ReadFSStat(info);
280
281 PRINT("netfs_read_fs_stat() done: %" B_PRIx32 " \n", error);
282
283 return error;
284 }
285
286 #if 0 // not used
287
288 // netfs_write_fs_stat
289 static
290 int
291 netfs_write_fs_stat(void *ns, struct fs_info *info, long mask)
292 {
293 VolumeManager* volumeManager = (VolumeManager*)ns;
294 Volume* volume = volumeManager->GetRootVolume();
295 VolumePutter _(volume);
296
297 PRINT("netfs_write_fs_stat(%p, %p, %ld)\n", ns, info, mask);
298
299 status_t error = B_BAD_VALUE;
300 if (volume)
301 error = volume->WriteFSStat(info, mask);
302
303 PRINT("netfs_write_fs_stat() done: %" B_PRIx32 " \n", error);
304
305 return error;
306 }
307
308 #endif
309
310 // #pragma mark -
311 // #pragma mark ----- vnodes -----
312
313 // netfs_read_vnode
314 static
315 int
netfs_read_vnode(void * ns,vnode_id vnid,char reenter,void ** node)316 netfs_read_vnode(void *ns, vnode_id vnid, char reenter, void **node)
317 {
318 VolumeManager* volumeManager = (VolumeManager*)ns;
319 Volume* volume = volumeManager->GetVolume(vnid);
320 VolumePutter _(volume);
321
322 PRINT("netfs_read_vnode(%p, %" B_PRIdINO ", %d, %p)\n", ns, vnid, reenter,
323 node);
324
325 status_t error = B_BAD_VALUE;
326 if (volume)
327 error = volume->ReadVNode(vnid, reenter, (Node**)node);
328
329 PRINT("netfs_read_vnode() done: (%" B_PRIx32 ", %p)\n", error, *node);
330
331 return error;
332 }
333
334 // netfs_write_vnode
335 static
336 int
netfs_write_vnode(void * ns,void * _node,char reenter)337 netfs_write_vnode(void *ns, void *_node, char reenter)
338 {
339 Node* node = (Node*)_node;
340 // DANGER: If dbg_printf() is used, this thread will enter another FS and
341 // even perform a write operation. The is dangerous here, since this hook
342 // may be called out of the other FSs, since, for instance a put_vnode()
343 // called from another FS may cause the VFS layer to free vnodes and thus
344 // invoke this hook.
345 // PRINT(("netfs_write_vnode(%p, %p, %d)\n", ns, node, reenter));
346 status_t error = node->GetVolume()->WriteVNode(node, reenter);
347 // PRINT(("netfs_write_vnode() done: %" B_PRIx32 "\n", error));
348 return error;
349 }
350
351 // netfs_remove_vnode
352 static
353 int
netfs_remove_vnode(void * ns,void * _node,char reenter)354 netfs_remove_vnode(void *ns, void *_node, char reenter)
355 {
356 Node* node = (Node*)_node;
357 // DANGER: See netfs_write_vnode().
358 // PRINT(("netfs_remove_vnode(%p, %p, %d)\n", ns, node, reenter));
359 status_t error = node->GetVolume()->RemoveVNode(node, reenter);
360 // PRINT(("netfs_remove_vnode() done: %" B_PRIx32 "\n", error));
361 return error;
362 }
363
364 // #pragma mark -
365 // #pragma mark ----- nodes -----
366
367 #if 0 // not used
368
369 // netfs_fsync
370 static
371 int
372 netfs_fsync(void *ns, void *_node)
373 {
374 Node* node = (Node*)_node;
375 PRINT("netfs_fsync(%p, %p)\n", ns, node);
376 status_t error = node->GetVolume()->FSync(node);
377 PRINT("netfs_fsync() done: %" B_PRIx32 "\n", error);
378 return error;
379 }
380
381 #endif
382
383 // netfs_read_stat
384 static
385 int
netfs_read_stat(void * ns,void * _node,struct stat * st)386 netfs_read_stat(void *ns, void *_node, struct stat *st)
387 {
388 Node* node = (Node*)_node;
389 PRINT("netfs_read_stat(%p, %p, %p)\n", ns, node, st);
390 status_t error = node->GetVolume()->ReadStat(node, st);
391 PRINT("netfs_read_stat() done: %" B_PRIx32 "\n", error);
392 return error;
393 }
394
395 // netfs_write_stat
396 static
397 int
netfs_write_stat(void * ns,void * _node,struct stat * st,long mask)398 netfs_write_stat(void *ns, void *_node, struct stat *st, long mask)
399 {
400 Node* node = (Node*)_node;
401 PRINT("netfs_write_stat(%p, %p, %p, %ld)\n", ns, node, st, mask);
402 status_t error = node->GetVolume()->WriteStat(node, st, mask);
403 PRINT("netfs_write_stat() done: %" B_PRIx32 "\n", error);
404 return error;
405 }
406
407 // netfs_access
408 static
409 int
netfs_access(void * ns,void * _node,int mode)410 netfs_access(void *ns, void *_node, int mode)
411 {
412 Node* node = (Node*)_node;
413 PRINT("netfs_access(%p, %p, %d)\n", ns, node, mode);
414 status_t error = node->GetVolume()->Access(node, mode);
415 PRINT("netfs_access() done: %" B_PRIx32 "\n", error);
416 return error;
417 }
418
419 // #pragma mark -
420 // #pragma mark ----- files -----
421
422 // netfs_create
423 static
424 int
netfs_create(void * ns,void * _dir,const char * name,int openMode,int mode,vnode_id * vnid,void ** cookie)425 netfs_create(void *ns, void *_dir, const char *name, int openMode, int mode,
426 vnode_id *vnid, void **cookie)
427 {
428 Node* dir = (Node*)_dir;
429 PRINT("netfs_create(%p, %p, `%s', %d, %d, %p, %p)\n", ns, dir,
430 name, openMode, mode, vnid, cookie);
431 status_t error = dir->GetVolume()->Create(dir, name, openMode, mode, vnid,
432 cookie);
433 PRINT("netfs_create() done: (%" B_PRIx32 ", %" B_PRIdINO ", %p)\n", error, *vnid,
434 *cookie);
435 return error;
436 }
437
438 // netfs_open
439 static
440 int
netfs_open(void * ns,void * _node,int openMode,void ** cookie)441 netfs_open(void *ns, void *_node, int openMode, void **cookie)
442 {
443 Node* node = (Node*)_node;
444 PRINT("netfs_open(%p, %p, %d)\n", ns, node, openMode);
445 status_t error = node->GetVolume()->Open(node, openMode, cookie);
446 PRINT("netfs_open() done: (%" B_PRIx32 ", %p)\n", error, *cookie);
447 return error;
448 }
449
450 // netfs_close
451 static
452 int
netfs_close(void * ns,void * _node,void * cookie)453 netfs_close(void *ns, void *_node, void *cookie)
454 {
455 Node* node = (Node*)_node;
456 PRINT("netfs_close(%p, %p, %p)\n", ns, node, cookie);
457 status_t error = node->GetVolume()->Close(node, cookie);
458 PRINT("netfs_close() done: %" B_PRIx32 "\n", error);
459 return error;
460 }
461
462 // netfs_free_cookie
463 static
464 int
netfs_free_cookie(void * ns,void * _node,void * cookie)465 netfs_free_cookie(void *ns, void *_node, void *cookie)
466 {
467 Node* node = (Node*)_node;
468 PRINT("netfs_free_cookie(%p, %p, %p)\n", ns, node, cookie);
469 status_t error = node->GetVolume()->FreeCookie(node, cookie);
470 PRINT("netfs_free_cookie() done: %" B_PRIx32 "\n", error);
471 return error;
472 }
473
474 // netfs_read
475 static
476 int
netfs_read(void * ns,void * _node,void * cookie,off_t pos,void * buffer,size_t * bufferSize)477 netfs_read(void *ns, void *_node, void *cookie, off_t pos, void *buffer,
478 size_t *bufferSize)
479 {
480 Node* node = (Node*)_node;
481 PRINT("netfs_read(%p, %p, %p, %" B_PRIdOFF ", %p, %lu)\n", ns, node,
482 cookie, pos, buffer, *bufferSize);
483 status_t error = node->GetVolume()->Read(node, cookie, pos, buffer,
484 *bufferSize, bufferSize);
485 PRINT("netfs_read() done: (%" B_PRIx32 ", %lu)\n", error, *bufferSize);
486 return error;
487 }
488
489 // netfs_write
490 static
491 int
netfs_write(void * ns,void * _node,void * cookie,off_t pos,const void * buffer,size_t * bufferSize)492 netfs_write(void *ns, void *_node, void *cookie, off_t pos,
493 const void *buffer, size_t *bufferSize)
494 {
495 Node* node = (Node*)_node;
496 PRINT("netfs_write(%p, %p, %p, %" B_PRIdOFF ", %p, %lu)\n", ns, node,
497 cookie, pos, buffer, *bufferSize);
498 status_t error = node->GetVolume()->Write(node, cookie, pos, buffer,
499 *bufferSize, bufferSize);
500 PRINT("netfs_write() done: (%" B_PRIx32 ", %lu)\n", error, *bufferSize);
501 return error;
502 }
503
504 // netfs_ioctl
505 static
506 int
netfs_ioctl(void * ns,void * _node,void * cookie,int cmd,void * buffer,size_t bufferSize)507 netfs_ioctl(void *ns, void *_node, void *cookie, int cmd, void *buffer,
508 size_t bufferSize)
509 {
510 Node* node = (Node*)_node;
511 PRINT("netfs_ioctl(%p, %p, %p, %d, %p, %lu)\n", ns, node, cookie, cmd,
512 buffer, bufferSize);
513 status_t error = node->GetVolume()->IOCtl(node, cookie, cmd, buffer,
514 bufferSize);
515 PRINT("netfs_ioctl() done: (%" B_PRIx32 ")\n", error);
516 return error;
517 }
518
519 // netfs_setflags
520 //static
521 //int
522 //netfs_setflags(void *ns, void *_node, void *cookie, int flags)
523 //{
524 // Node* node = (Node*)_node;
525 // PRINT(("netfs_setflags(%p, %p, %p, %d)\n", ns, node, cookie, flags));
526 // status_t error = node->GetVolume()->SetFlags(node, cookie, flags);
527 // PRINT(("netfs_setflags() done: (%lx)\n", error));
528 // return error;
529 //}
530
531 // #pragma mark -
532 // #pragma mark ----- hard links / symlinks -----
533
534 // netfs_link
535 static
536 int
netfs_link(void * ns,void * _dir,const char * name,void * _node)537 netfs_link(void *ns, void *_dir, const char *name, void *_node)
538 {
539 Node* dir = (Node*)_dir;
540 Node* node = (Node*)_node;
541 PRINT("netfs_link(%p, %p, `%s', %p)\n", ns, dir, name, node);
542 status_t error = dir->GetVolume()->Link(dir, name, node);
543 PRINT("netfs_link() done: (%" B_PRIx32 ")\n", error);
544 return error;
545 }
546
547 // netfs_unlink
548 static
549 int
netfs_unlink(void * ns,void * _dir,const char * name)550 netfs_unlink(void *ns, void *_dir, const char *name)
551 {
552 Node* dir = (Node*)_dir;
553 PRINT("netfs_unlink(%p, %p, `%s')\n", ns, dir, name);
554 status_t error = dir->GetVolume()->Unlink(dir, name);
555 PRINT("netfs_unlink() done: (%" B_PRIx32 ")\n", error);
556 return error;
557 }
558
559 // netfs_symlink
560 static
561 int
netfs_symlink(void * ns,void * _dir,const char * name,const char * path)562 netfs_symlink(void *ns, void *_dir, const char *name, const char *path)
563 {
564 Node* dir = (Node*)_dir;
565 PRINT("netfs_symlink(%p, %p, `%s', `%s')\n", ns, dir, name, path);
566 status_t error = dir->GetVolume()->Symlink(dir, name, path);
567 PRINT("netfs_symlink() done: (%" B_PRIx32 ")\n", error);
568 return error;
569 }
570
571 // netfs_read_link
572 static
573 int
netfs_read_link(void * ns,void * _node,char * buffer,size_t * bufferSize)574 netfs_read_link(void *ns, void *_node, char *buffer, size_t *bufferSize)
575 {
576 Node* node = (Node*)_node;
577 PRINT("netfs_read_link(%p, %p, %p, %lu)\n", ns, node, buffer,
578 *bufferSize);
579
580 // TODO: If this were to be implemented (which it isn't, it currently just
581 // returns B_BAD_VALUE) then this will need to be changed to return the
582 // length of the node and not the number of bytes read into buffer.
583 status_t error = node->GetVolume()->ReadLink(node, buffer, *bufferSize,
584 bufferSize);
585 PRINT("netfs_read_link() done: (%" B_PRIx32 ", %lu)\n", error,
586 *bufferSize);
587 return error;
588 }
589
590 // netfs_rename
591 static
592 int
netfs_rename(void * ns,void * _oldDir,const char * oldName,void * _newDir,const char * newName)593 netfs_rename(void *ns, void *_oldDir, const char *oldName, void *_newDir,
594 const char *newName)
595 {
596 Node* oldDir = (Node*)_oldDir;
597 Node* newDir = (Node*)_newDir;
598 PRINT("netfs_rename(%p, %p, `%s', %p, `%s')\n", ns, oldDir, oldName,
599 newDir, newName);
600 status_t error = oldDir->GetVolume()->Rename(oldDir, oldName,
601 newDir, newName);
602 PRINT("netfs_rename() done: (%" B_PRIx32 ")\n", error);
603 return error;
604 }
605
606 // #pragma mark -
607 // #pragma mark ----- directories -----
608
609 // netfs_mkdir
610 static
611 int
netfs_mkdir(void * ns,void * _dir,const char * name,int mode)612 netfs_mkdir(void *ns, void *_dir, const char *name, int mode)
613 {
614 Node* dir = (Node*)_dir;
615 PRINT("netfs_mkdir(%p, %p, `%s', %d)\n", ns, dir, name, mode);
616 status_t error = dir->GetVolume()->MkDir(dir, name, mode);
617 PRINT("netfs_mkdir() done: (%" B_PRIx32 ")\n", error);
618 return error;
619 }
620
621 // netfs_rmdir
622 static
623 int
netfs_rmdir(void * ns,void * _dir,const char * name)624 netfs_rmdir(void *ns, void *_dir, const char *name)
625 {
626 Node* dir = (Node*)_dir;
627 PRINT("netfs_rmdir(%p, %p, `%s')\n", ns, dir, name);
628 status_t error = dir->GetVolume()->RmDir(dir, name);
629 PRINT("netfs_rmdir() done: (%" B_PRIx32 ")\n", error);
630 return error;
631 }
632
633 // netfs_open_dir
634 static
635 int
netfs_open_dir(void * ns,void * _node,void ** cookie)636 netfs_open_dir(void *ns, void *_node, void **cookie)
637 {
638 Node* node = (Node*)_node;
639 PRINT("netfs_open_dir(%p, %p)\n", ns, node);
640 status_t error = node->GetVolume()->OpenDir(node, cookie);
641 PRINT("netfs_open_dir() done: (%" B_PRIx32 ", %p)\n", error, *cookie);
642 return error;
643 }
644
645 // netfs_close_dir
646 static
647 int
netfs_close_dir(void * ns,void * _node,void * cookie)648 netfs_close_dir(void *ns, void *_node, void *cookie)
649 {
650 Node* node = (Node*)_node;
651 PRINT("netfs_close_dir(%p, %p, %p)\n", ns, node, cookie);
652 status_t error = node->GetVolume()->CloseDir(node, cookie);
653 PRINT("netfs_close_dir() done: %" B_PRIx32 "\n", error);
654 return error;
655 }
656
657 // netfs_free_dir_cookie
658 static
659 int
netfs_free_dir_cookie(void * ns,void * _node,void * cookie)660 netfs_free_dir_cookie(void *ns, void *_node, void *cookie)
661 {
662 Node* node = (Node*)_node;
663 PRINT("netfs_free_dir_cookie(%p, %p, %p)\n", ns, node, cookie);
664 status_t error = node->GetVolume()->FreeDirCookie(node, cookie);
665 PRINT("netfs_free_dir_cookie() done: %" B_PRIx32 " \n", error);
666 return error;
667 }
668
669 // netfs_read_dir
670 static
671 int
netfs_read_dir(void * ns,void * _node,void * cookie,long * count,struct dirent * buffer,size_t bufferSize)672 netfs_read_dir(void *ns, void *_node, void *cookie, long *count,
673 struct dirent *buffer, size_t bufferSize)
674 {
675 Node* node = (Node*)_node;
676 PRINT("netfs_read_dir(%p, %p, %p, %ld, %p, %lu)\n", ns, node, cookie,
677 *count, buffer, bufferSize);
678 int32 _count = *count;
679 status_t error = node->GetVolume()->ReadDir(node, cookie, buffer,
680 bufferSize, _count, &_count);
681 *count = _count;
682 PRINT("netfs_read_dir() done: (%" B_PRIx32 ", %ld)\n", error, *count);
683 #if DEBUG
684 dirent* entry = buffer;
685 for (int32 i = 0; i < *count; i++) {
686 // R5's kernel vsprintf() doesn't seem to know `%.<number>s', so
687 // we need to work around.
688 char name[B_FILE_NAME_LENGTH];
689 int nameLen = strnlen(entry->d_name, B_FILE_NAME_LENGTH - 1);
690 strncpy(name, entry->d_name, nameLen);
691 name[nameLen] = '\0';
692 PRINT(" entry: d_dev: %" B_PRIdDEV ", d_pdev: %" B_PRIdDEV
693 ", d_ino: %" B_PRIdINO ", d_pino: %" B_PRIdINO
694 ", d_reclen: %hu, d_name: `%s'\n",
695 entry->d_dev, entry->d_pdev, entry->d_ino,
696 entry->d_pino, entry->d_reclen, name);
697 entry = (dirent*)((char*)entry + entry->d_reclen);
698 }
699 #endif
700
701 return error;
702 }
703
704 // netfs_rewind_dir
705 static
706 int
netfs_rewind_dir(void * ns,void * _node,void * cookie)707 netfs_rewind_dir(void *ns, void *_node, void *cookie)
708 {
709 Node* node = (Node*)_node;
710 PRINT("netfs_rewind_dir(%p, %p, %p)\n", ns, node, cookie);
711 status_t error = node->GetVolume()->RewindDir(node, cookie);
712 PRINT("netfs_rewind_dir() done: %" B_PRIx32 "\n", error);
713 return error;
714 }
715
716 // netfs_walk
717 static
718 int
netfs_walk(void * ns,void * _dir,const char * entryName,char ** resolvedPath,vnode_id * vnid)719 netfs_walk(void *ns, void *_dir, const char *entryName,
720 char **resolvedPath, vnode_id *vnid)
721 {
722 Node* dir = (Node*)_dir;
723 PRINT("netfs_walk(%p, %p, `%s', %p, %p)\n", ns, dir,
724 entryName, resolvedPath, vnid);
725 status_t error = dir->GetVolume()->Walk(dir, entryName, resolvedPath, vnid);
726 PRINT("netfs_walk() done: (%" B_PRIx32 ", `%s', %" B_PRIdINO ")\n", error,
727 (resolvedPath ? *resolvedPath : NULL), *vnid);
728 return error;
729 }
730
731 // #pragma mark -
732 // #pragma mark ----- attributes -----
733
734 // netfs_open_attrdir
735 static
736 int
netfs_open_attrdir(void * ns,void * _node,void ** cookie)737 netfs_open_attrdir(void *ns, void *_node, void **cookie)
738 {
739 Node* node = (Node*)_node;
740 PRINT("netfs_open_attrdir(%p, %p)\n", ns, node);
741 status_t error = node->GetVolume()->OpenAttrDir(node, cookie);
742 PRINT("netfs_open_attrdir() done: (%" B_PRIx32 ", %p)\n", error, *cookie);
743 return error;
744 }
745
746 // netfs_close_attrdir
747 static
748 int
netfs_close_attrdir(void * ns,void * _node,void * cookie)749 netfs_close_attrdir(void *ns, void *_node, void *cookie)
750 {
751 Node* node = (Node*)_node;
752 PRINT("netfs_close_attrdir(%p, %p, %p)\n", ns, node, cookie);
753 status_t error = node->GetVolume()->CloseAttrDir(node, cookie);
754 PRINT("netfs_close_attrdir() done: (%" B_PRIx32 ")\n", error);
755 return error;
756 }
757
758 // netfs_free_attrdir_cookie
759 static
760 int
netfs_free_attrdir_cookie(void * ns,void * _node,void * cookie)761 netfs_free_attrdir_cookie(void *ns, void *_node, void *cookie)
762 {
763 Node* node = (Node*)_node;
764 PRINT("netfs_free_attrdir_cookie(%p, %p, %p)\n", ns, node, cookie);
765 status_t error = node->GetVolume()->FreeAttrDirCookie(node, cookie);
766 PRINT("netfs_free_attrdir_cookie() done: (%" B_PRIx32 ")\n", error);
767 return error;
768 }
769
770 // netfs_read_attrdir
771 static
772 int
netfs_read_attrdir(void * ns,void * _node,void * cookie,long * count,struct dirent * buffer,size_t bufferSize)773 netfs_read_attrdir(void *ns, void *_node, void *cookie, long *count,
774 struct dirent *buffer, size_t bufferSize)
775 {
776 Node* node = (Node*)_node;
777 PRINT("netfs_read_attrdir(%p, %p, %p, %ld, %p, %lu)\n", ns, node,
778 cookie, *count, buffer, bufferSize);
779 int32 _count = *count;
780 status_t error = node->GetVolume()->ReadAttrDir(node, cookie, buffer,
781 bufferSize, _count, &_count);
782 *count = _count;
783 PRINT("netfs_read_attrdir() done: (%" B_PRIx32 ", %ld)\n", error, *count);
784 return error;
785 }
786
787 // netfs_rewind_attrdir
788 static
789 int
netfs_rewind_attrdir(void * ns,void * _node,void * cookie)790 netfs_rewind_attrdir(void *ns, void *_node, void *cookie)
791 {
792 Node* node = (Node*)_node;
793 PRINT("netfs_rewind_attrdir(%p, %p, %p)\n", ns, node, cookie);
794 status_t error = node->GetVolume()->RewindAttrDir(node, cookie);
795 PRINT("netfs_rewind_attrdir() done: (%" B_PRIx32 ")\n", error);
796 return error;
797 }
798
799 // netfs_read_attr
800 static
801 int
netfs_read_attr(void * ns,void * _node,const char * name,int type,void * buffer,size_t * bufferSize,off_t pos)802 netfs_read_attr(void *ns, void *_node, const char *name, int type,
803 void *buffer, size_t *bufferSize, off_t pos)
804 {
805 Node* node = (Node*)_node;
806 PRINT("netfs_read_attr(%p, %p, `%s', %d, %p, %lu, %" B_PRIdOFF ")\n", ns,
807 node, name, type, buffer, *bufferSize, pos);
808 status_t error = node->GetVolume()->ReadAttr(node, name, type, pos, buffer,
809 *bufferSize, bufferSize);
810 PRINT("netfs_read_attr() done: (%" B_PRIx32 ", %ld)\n", error,
811 *bufferSize);
812 return error;
813 }
814
815 // netfs_write_attr
816 static
817 int
netfs_write_attr(void * ns,void * _node,const char * name,int type,const void * buffer,size_t * bufferSize,off_t pos)818 netfs_write_attr(void *ns, void *_node, const char *name, int type,
819 const void *buffer, size_t *bufferSize, off_t pos)
820 {
821 Node* node = (Node*)_node;
822 PRINT("netfs_write_attr(%p, %p, `%s', %d, %p, %lu, %" B_PRIdOFF ")\n", ns,
823 node, name, type, buffer, *bufferSize, pos);
824 status_t error = node->GetVolume()->WriteAttr(node, name, type, pos, buffer,
825 *bufferSize, bufferSize);
826 PRINT("netfs_write_attr() done: (%" B_PRIx32 ", %ld)\n", error,
827 *bufferSize);
828 return error;
829 }
830
831 // netfs_remove_attr
832 static
833 int
netfs_remove_attr(void * ns,void * _node,const char * name)834 netfs_remove_attr(void *ns, void *_node, const char *name)
835 {
836 Node* node = (Node*)_node;
837 PRINT("netfs_remove_attr(%p, %p, `%s')\n", ns, node, name);
838 status_t error = node->GetVolume()->RemoveAttr(node, name);
839 PRINT("netfs_remove_attr() done: (%" B_PRIx32 ")\n", error);
840 return error;
841 }
842
843 // netfs_rename_attr
844 static
845 int
netfs_rename_attr(void * ns,void * _node,const char * oldName,const char * newName)846 netfs_rename_attr(void *ns, void *_node, const char *oldName,
847 const char *newName)
848 {
849 Node* node = (Node*)_node;
850 PRINT("netfs_rename_attr(%p, %p, `%s', `%s')\n", ns, node, oldName,
851 newName);
852 status_t error = node->GetVolume()->RenameAttr(node, oldName, newName);
853 PRINT("netfs_rename_attr() done: (%" B_PRIx32 ")\n", error);
854 return error;
855 }
856
857 // netfs_stat_attr
858 static
859 int
netfs_stat_attr(void * ns,void * _node,const char * name,struct attr_info * attrInfo)860 netfs_stat_attr(void *ns, void *_node, const char *name,
861 struct attr_info *attrInfo)
862 {
863 Node* node = (Node*)_node;
864 PRINT("netfs_stat_attr(%p, %p, `%s', %p)\n", ns, node, name,
865 attrInfo);
866 status_t error = node->GetVolume()->StatAttr(node, name, attrInfo);
867 PRINT("netfs_stat_attr() done: (%" B_PRIx32 ")\n", error);
868 return error;
869 }
870
871 // #pragma mark -
872 // #pragma mark ----- queries -----
873
874 // netfs_open_query
875 static
876 int
netfs_open_query(void * ns,const char * queryString,ulong flags,port_id port,long token,void ** cookie)877 netfs_open_query(void *ns, const char *queryString, ulong flags,
878 port_id port, long token, void **cookie)
879 {
880 VolumeManager* volumeManager = (VolumeManager*)ns;
881 Volume* volume = volumeManager->GetRootVolume();
882 VolumePutter _(volume);
883
884 PRINT("netfs_open_query(%p, `%s', %lu, %" B_PRId32 ", %ld, %p)\n", ns,
885 queryString, flags, port, token, cookie);
886
887 status_t error = B_BAD_VALUE;
888 if (volume) {
889 error = volume->OpenQuery(queryString, flags, port, token,
890 (QueryIterator**)cookie);
891 }
892
893 PRINT("netfs_open_query() done: (%" B_PRIx32 ", %p)\n", error, *cookie);
894 return error;
895 }
896
897 // netfs_close_query
898 static
899 int
netfs_close_query(void * ns,void * cookie)900 netfs_close_query(void *ns, void *cookie)
901 {
902 PRINT("netfs_close_query(%p, %p)\n", ns, cookie);
903
904 status_t error = B_OK;
905 // no-op: we don't use this hook
906
907 PRINT("netfs_close_query() done: (%" B_PRIx32 ")\n", error);
908 return error;
909 }
910
911 // netfs_free_query_cookie
912 static
913 int
netfs_free_query_cookie(void * ns,void * node,void * cookie)914 netfs_free_query_cookie(void *ns, void *node, void *cookie)
915 {
916 VolumeManager* volumeManager = (VolumeManager*)ns;
917 QueryIterator* iterator = (QueryIterator*)cookie;
918
919 PRINT("netfs_free_query_cookie(%p, %p)\n", ns, cookie);
920
921 status_t error = B_OK;
922 volumeManager->GetQueryManager()->PutIterator(iterator);
923
924 PRINT("netfs_free_query_cookie() done: (%" B_PRIx32 ")\n", error);
925 return error;
926 }
927
928 // netfs_read_query
929 static
930 int
netfs_read_query(void * ns,void * cookie,long * count,struct dirent * buffer,size_t bufferSize)931 netfs_read_query(void *ns, void *cookie, long *count,
932 struct dirent *buffer, size_t bufferSize)
933 {
934 VolumeManager* volumeManager = (VolumeManager*)ns;
935 Volume* volume = volumeManager->GetRootVolume();
936 QueryIterator* iterator = (QueryIterator*)cookie;
937 VolumePutter _(volume);
938
939 PRINT("netfs_read_query(%p, %p, %ld, %p, %lu)\n", ns, cookie,
940 *count, buffer, bufferSize);
941
942 status_t error = B_BAD_VALUE;
943 if (volume) {
944 int32 _count = *count;
945 error = volume->ReadQuery(iterator, buffer, bufferSize,
946 _count, &_count);
947 *count = _count;
948 }
949
950 PRINT("netfs_read_query() done: (%" B_PRIx32 ", %ld)\n", error, *count);
951 return error;
952 }
953
954