2 ** Copyright 2001, Travis Geiselbrecht. All rights reserved.
3 ** Distributed under the terms of the NewOS License.
5 /* Initial coding by Ithamar Adema, 2001 */
7 #include <kernel/kernel.h>
8 #include <kernel/vfs.h>
10 #include <kernel/khash.h> // for vnode hash table handling
11 #include <kernel/heap.h> // for kmalloc / kfree
12 #include <kernel/lock.h> // for mutex handling
13 #include <kernel/vm.h>
19 //================================================================================
20 // DEBUGGING FUNCTIONALITY
21 //================================================================================
23 #include <kernel/console.h> // for kprintf
24 #include <kernel/debug.h>
29 #define TRACE(x) kprintf x
34 //================================================================================
35 // PRIVATE STRUCTURES FUNCTIONALITY
36 //================================================================================
38 #define ISOFS_HASH_SIZE 16
40 // our private filesystem structure
42 int fd
; // filedescriptor for ISO9660 file/dev
43 fs_id id
; // vfs filesystem id
45 int next_vnode_id
; // next available vnode id
46 void *vnode_list_hash
; // hashtable of all used vnodes
47 struct isofs_vnode
*root_vnode
; // pointer to private vnode struct of root dir of fs
50 char volumename
[33];// name of volume
51 size_t blocksize
; // Size of an ISO sector
52 long numblocks
; // Number of sectors on ISO image
55 //--------------------------------------------------------------------------------
57 struct isofs_stream
*s
;
61 off_t pos
; // Position in directory/file data
64 struct isofs_vnode
* ptr
;
69 //--------------------------------------------------------------------------------
70 // our private stream structure
72 stream_type type
; // is this stream a directory or file?
73 off_t desc_pos
; // position in ISO of dir descriptor
74 off_t data_pos
; // position in ISO of dir data
75 size_t data_len
; // length of data
76 struct isofs_vnode
*dir_head
; // Pointer to first entry in directory
79 //--------------------------------------------------------------------------------
80 // our private vnode structure
82 struct isofs_vnode
*all_next
; // next ptr of the global vnode linked-list (for hash)
83 vnode_id id
; // our mapping back to vfs vnodes
84 char *name
; // name of this vnode
85 struct isofs_vnode
*parent
; // vnode of parent (directory)
86 struct isofs_vnode
*dir_next
; // vnode of next entry in parent
87 struct isofs_stream stream
; // private stream info
88 bool scanned
; // true if dir has been scanned, false if not
91 static void iso_scan_dir(struct isofs
* fs
, struct isofs_vnode
* dir
);
93 //--------------------------------------------------------------------------------
94 static unsigned int isofs_vnode_hash_func(void *_v
, const void *_key
, unsigned int range
)
96 struct isofs_vnode
*v
= _v
; // convenience ptr to our vnode structure
97 const vnode_id
*key
= _key
; // convenience ptr to vfs vnode ID
99 if(v
!= NULL
) // If we've got a private vnode structure
100 return v
->id
% range
; // use that to calc hash value
102 return (*key
) % range
; // use kernel vnode id
105 //--------------------------------------------------------------------------------
106 static int isofs_vnode_compare_func(void *_v
, const void *_key
)
108 struct isofs_vnode
*v
= _v
; // convenience ptr to our vnode structure
109 const vnode_id
*key
= _key
; // convenience ptr to vfs vnode ID
111 if(v
->id
== *key
) // If the passed kernel vnode ID == private vnode ID
112 return 0; // we're the same!
114 return -1; // nope, not equal :(
117 //--------------------------------------------------------------------------------
118 static struct isofs_vnode
*isofs_create_vnode(struct isofs
*fs
, const char *name
)
120 struct isofs_vnode
*v
; // private vnode structure to be created
122 // try to allocate our private vnode structure
123 v
= kmalloc(sizeof(struct isofs_vnode
));
124 if(v
== NULL
) // return NULL if not able to
127 // initialize our vnode structure
128 memset(v
, 0, sizeof(struct isofs_vnode
));
129 v
->id
= fs
->next_vnode_id
++;
131 // copy name of vnode
132 v
->name
= kmalloc(strlen(name
) + 1);
133 if(v
->name
== NULL
) {
137 strcpy(v
->name
, name
);
139 // return newly allocated private vnode structure
143 //--------------------------------------------------------------------------------
144 static int isofs_delete_vnode(struct isofs
*fs
, struct isofs_vnode
*v
, bool force_delete
)
146 // cant delete it if it's in a directory or is a directory
149 // if(!force_delete && ((v->stream.type == STREAM_TYPE_DIR && v->stream.u.dir.dir_head != NULL) || v->dir_next != NULL)) {
150 // return ERR_NOT_ALLOWED;
153 // remove it from the global hash table
154 hash_remove(fs
->vnode_list_hash
, v
);
160 // free vnode structure itself
163 // Tell caller all is ok
167 //--------------------------------------------------------------------------------
168 static int isofs_insert_in_dir(struct isofs_vnode
*dir
, struct isofs_vnode
*v
)
170 if(dir
->stream
.type
!= STREAM_TYPE_DIR
)
171 return ERR_INVALID_ARGS
;
173 v
->dir_next
= dir
->stream
.dir_head
;
174 dir
->stream
.dir_head
= v
;
180 //--------------------------------------------------------------------------------
181 static struct isofs_vnode
* isofs_find_in_dir(struct isofs
*fs
, struct isofs_vnode
* dir
, const char* path
)
183 struct isofs_vnode
*v
;
185 if(dir
->stream
.type
!= STREAM_TYPE_DIR
)
188 iso_scan_dir(fs
, dir
);
190 for(v
= dir
->stream
.dir_head
; v
; v
= v
->dir_next
) {
191 if(strcmp(v
->name
, path
) == 0) {
199 //================================================================================
200 // ISO9660 FORMAT HANDLING
201 //================================================================================
202 #define ISODIRENTRYBUF_SIZE sizeof(iso_dir_entry)+32
204 static struct isofs_vnode
* iso_add_entry(struct isofs
* fs
, struct isofs_vnode
* parent
,
205 iso_dir_entry
* e
, off_t desc_pos
)
207 struct isofs_vnode
* v
;
210 // Create ASCIIZ name
211 strncpy(name
, e
->name
, e
->nameLength
);
212 name
[e
->nameLength
] = '\0';
214 // Create initial vnode
215 v
= isofs_create_vnode(fs
,name
);
217 // Fill in the stream member of the vnode
218 v
->stream
.type
= (e
->flags
& 2) ? STREAM_TYPE_DIR
: STREAM_TYPE_FILE
;
219 v
->stream
.desc_pos
= desc_pos
;
220 v
->stream
.data_pos
= e
->dataStartSector
[ISO_LSB_INDEX
] * fs
->blocksize
;
221 v
->stream
.data_len
= e
->dataLength
[ISO_LSB_INDEX
];
223 // Insert it into the hierarchy
224 if (parent
!= NULL
) {
225 isofs_insert_in_dir(parent
,v
);
230 // Insert it into our hashing table
231 hash_insert(fs
->vnode_list_hash
, v
);
236 //--------------------------------------------------------------------------------
237 static void iso_scan_dir(struct isofs
* fs
, struct isofs_vnode
* dir
)
239 char entryBuf
[ISODIRENTRYBUF_SIZE
];
248 start
= dir
->stream
.data_pos
;
249 end
= start
+ dir
->stream
.data_len
;
253 sys_read(fs
->fd
, entryBuf
, start
, ISODIRENTRYBUF_SIZE
);
254 e
= (iso_dir_entry
*)&entryBuf
[0];
256 if (e
->recordLength
== 0) {
259 // Check for . and .. entries and correct name
260 if (cnt
== 0 && e
->nameLength
<= 1 && e
->name
[0] < 32) {
261 strcpy(e
->name
, ".");
263 } else if (cnt
== 1 && e
->nameLength
<= 1 && e
->name
[0] < 32) {
264 strcpy(e
->name
, "..");
268 iso_add_entry(fs
, dir
, e
, start
);
269 start
+= e
->recordLength
;
272 } while( start
< end
);
277 //--------------------------------------------------------------------------------
278 static void iso_init_volume(struct isofs
* fs
)
280 iso_volume_descriptor voldesc
;
283 // Read ISO9660 volume descriptor
284 sys_read(fs
->fd
, &voldesc
, ISO_VD_START
, sizeof(voldesc
));
287 strncpy(fs
->volumename
, voldesc
.volumeID
, 32);
288 fs
->volumename
[32] = '\0';
290 // Copy block size + # of blocks
291 fs
->blocksize
= voldesc
.sectorSize
[ISO_LSB_INDEX
];
292 fs
->numblocks
= voldesc
.numSectors
[ISO_LSB_INDEX
];
294 // Get pointer to root directory entry
295 e
= (iso_dir_entry
*)&voldesc
.rootDirEntry
[0];
297 // Setup our root directory
298 fs
->root_vnode
= iso_add_entry(fs
, NULL
, e
,
299 ISO_VD_START
+ voldesc
.rootDirEntry
- &voldesc
.type
);
302 //================================================================================
303 // VFS DRIVER API IMPLEMENTATION
304 //================================================================================
306 static int isofs_mount(fs_cookie
*_fs
, fs_id id
, const char *device
, void *args
, vnode_id
*root_vnid
)
309 struct isofs_vnode
*v
;
312 TRACE(("isofs_mount: entry\n"));
314 fs
= kmalloc(sizeof(struct isofs
));
321 fs
->next_vnode_id
= 0;
323 // Try to open the ISO file to read
324 fs
->fd
= sys_open(device
, 0);
330 err
= mutex_init(&fs
->lock
, "isofs_mutex");
335 // Create and setup hash table
336 fs
->vnode_list_hash
= hash_init(ISOFS_HASH_SIZE
, offsetof(struct isofs_vnode
, all_next
),
337 &isofs_vnode_compare_func
, &isofs_vnode_hash_func
);
338 if(fs
->vnode_list_hash
== NULL
) {
343 // Read the ISO9660 info, and create root vnode
346 *root_vnid
= fs
->root_vnode
->id
;
351 isofs_delete_vnode(fs
, v
, true);
352 hash_uninit(fs
->vnode_list_hash
);
354 mutex_destroy(&fs
->lock
);
361 //--------------------------------------------------------------------------------
362 static int isofs_unmount(fs_cookie _fs
)
364 struct isofs
*fs
= _fs
;
365 struct isofs_vnode
*v
;
366 struct hash_iterator i
;
368 TRACE(("isofs_unmount: entry fs = 0x%x\n", fs
));
370 // delete all of the vnodes
371 hash_open(fs
->vnode_list_hash
, &i
);
372 while((v
= (struct isofs_vnode
*)hash_next(fs
->vnode_list_hash
, &i
)) != NULL
) {
373 isofs_delete_vnode(fs
, v
, true);
375 hash_close(fs
->vnode_list_hash
, &i
, false);
377 hash_uninit(fs
->vnode_list_hash
);
378 mutex_destroy(&fs
->lock
);
385 //--------------------------------------------------------------------------------
386 static int isofs_sync(fs_cookie fs
)
388 TRACE(("isofs_sync: entry\n"));
393 //--------------------------------------------------------------------------------
394 static int isofs_lookup(fs_cookie _fs
, fs_vnode _dir
, const char *name
, vnode_id
*id
)
396 struct isofs
*fs
= (struct isofs
*)_fs
;
397 struct isofs_vnode
*dir
= (struct isofs_vnode
*)_dir
;
398 struct isofs_vnode
*v
;
399 struct isofs_vnode
*v1
;
402 TRACE(("isofs_lookup: entry dir 0x%x, name '%s'\n", dir
, name
));
404 if(dir
->stream
.type
!= STREAM_TYPE_DIR
)
405 return ERR_VFS_NOT_DIR
;
407 mutex_lock(&fs
->lock
);
410 v
= isofs_find_in_dir(fs
, dir
, name
);
416 err
= vfs_get_vnode(fs
->id
, v
->id
, (fs_vnode
*)&v1
);
426 mutex_unlock(&fs
->lock
);
431 //--------------------------------------------------------------------------------
432 static int isofs_getvnode(fs_cookie _fs
, vnode_id id
, fs_vnode
*v
, bool r
)
434 struct isofs
*fs
= (struct isofs
*)_fs
;
436 TRACE(("isofs_getvnode: asking for vnode 0x%x 0x%x, r %d\n", id
, r
));
439 mutex_lock(&fs
->lock
);
441 *v
= hash_lookup(fs
->vnode_list_hash
, &id
);
444 mutex_unlock(&fs
->lock
);
446 TRACE(("isofs_getnvnode: looked it up at 0x%x\n", *v
));
451 return ERR_NOT_FOUND
;
454 //--------------------------------------------------------------------------------
455 static int isofs_putvnode(fs_cookie _fs
, fs_vnode _v
, bool r
)
457 struct isofs_vnode
*v
= (struct isofs_vnode
*)_v
;
461 TRACE(("isofs_putvnode: entry on vnode 0x%x 0x%x, r %d\n", v
->id
, r
));
463 return 0; // whatever
466 static int isofs_removevnode(fs_cookie _fs
, fs_vnode _v
, bool r
)
468 struct isofs
*fs
= (struct isofs
*)_fs
;
469 struct isofs_vnode
*v
= (struct isofs_vnode
*)_v
;
472 TRACE(("isofs_removevnode: remove 0x%x (0x%x 0x%x), r %d\n", v
, v
->id
, r
));
475 mutex_lock(&fs
->lock
);
478 // can't remove node if it's linked to the dir
479 panic("isofs_removevnode: vnode %p asked to be removed is present in dir\n", v
);
482 isofs_delete_vnode(fs
, v
, false);
487 mutex_unlock(&fs
->lock
);
492 //--------------------------------------------------------------------------------
493 static int isofs_fsync(fs_cookie _fs
, fs_vnode _v
)
495 struct isofs_vnode
*v
= (struct isofs_vnode
*)_v
;
499 TRACE(("isofs_fsync: entry on vnode 0x%x\n", v
->id
));
503 //--------------------------------------------------------------------------------
504 static int isofs_opendir(fs_cookie _fs
, fs_vnode _v
, dir_cookie
*_cookie
)
506 struct isofs
*fs
= (struct isofs
*)_fs
;
507 struct isofs_vnode
*v
= (struct isofs_vnode
*)_v
;
508 struct isofs_cookie
*cookie
;
511 TRACE(("isofs_opendir: vnode 0x%x\n", v
));
513 if(v
->stream
.type
!= STREAM_TYPE_DIR
)
514 return ERR_VFS_NOT_DIR
;
516 cookie
= kmalloc(sizeof(struct isofs_cookie
));
518 return ERR_NO_MEMORY
;
520 mutex_lock(&fs
->lock
);
523 cookie
->u
.dir
.ptr
= v
->stream
.dir_head
;
527 mutex_unlock(&fs
->lock
);
531 //--------------------------------------------------------------------------------
532 static int isofs_closedir(fs_cookie _fs
, fs_vnode _v
, dir_cookie _cookie
)
534 struct isofs
*fs
= _fs
;
535 struct isofs_vnode
*v
= _v
;
536 struct isofs_cookie
*cookie
= _cookie
;
538 TOUCH(fs
);TOUCH(v
);TOUCH(cookie
);
540 TRACE(("isofs_closedir: entry vnode 0x%x, cookie 0x%x\n", v
, cookie
));
542 if(v
->stream
.type
!= STREAM_TYPE_DIR
)
543 return ERR_VFS_NOT_DIR
;
552 //--------------------------------------------------------------------------------
553 static int isofs_rewinddir(fs_cookie _fs
, fs_vnode _v
, dir_cookie _cookie
)
555 struct isofs_vnode
*v
= _v
;
556 struct isofs_cookie
*cookie
= _cookie
;
561 TRACE(("isofs_rewinddir: vnode 0x%x, cookie 0x%x\n", v
, cookie
));
563 if(v
->stream
.type
!= STREAM_TYPE_DIR
)
564 return ERR_VFS_NOT_DIR
;
566 cookie
->u
.dir
.ptr
= cookie
->s
->dir_head
;
571 //--------------------------------------------------------------------------------
572 static int isofs_readdir(fs_cookie _fs
, fs_vnode _v
, dir_cookie _cookie
, void *buf
, size_t len
)
574 struct isofs
*fs
= _fs
;
575 struct isofs_vnode
*v
= _v
;
576 struct isofs_cookie
*cookie
= _cookie
;
581 TRACE(("isofs_readdir: vnode 0x%x, cookie 0x%x, len 0x%x\n", v
, cookie
, len
));
583 if(v
->stream
.type
!= STREAM_TYPE_DIR
)
584 return ERR_VFS_NOT_DIR
;
586 if(cookie
->u
.dir
.ptr
== NULL
)
589 mutex_lock(&fs
->lock
);
591 if(strlen(cookie
->u
.dir
.ptr
->name
) + 1 > len
) {
592 err
= ERR_VFS_INSUFFICIENT_BUF
;
596 err
= user_strcpy(buf
, cookie
->u
.dir
.ptr
->name
);
600 err
= strlen(cookie
->u
.dir
.ptr
->name
) + 1;
602 cookie
->u
.dir
.ptr
= cookie
->u
.dir
.ptr
->dir_next
;
605 mutex_unlock(&fs
->lock
);
610 //--------------------------------------------------------------------------------
611 static int isofs_open(fs_cookie _fs
, fs_vnode _v
, file_cookie
*_cookie
, int oflags
)
613 struct isofs_vnode
*v
= _v
;
614 struct isofs_cookie
*cookie
;
617 TRACE(("isofs_open: vnode 0x%x, oflags 0x%x\n", v
, oflags
));
619 if(v
->stream
.type
== STREAM_TYPE_DIR
)
620 return ERR_VFS_IS_DIR
;
622 // Allocate our cookie for storage of position
623 cookie
= kmalloc(sizeof(struct isofs_cookie
));
629 // Setup our cookie to start of stream data
630 cookie
->s
= &v
->stream
;
631 cookie
->u
.file
.pos
= 0;
633 // Give cookie to caller
639 //--------------------------------------------------------------------------------
640 static int isofs_close(fs_cookie _fs
, fs_vnode _v
, file_cookie _cookie
)
642 struct isofs_vnode
*v
= _v
;
643 struct isofs_cookie
*cookie
= _cookie
;
645 TOUCH(v
); TOUCH(cookie
);
647 TRACE(("isofs_close: entry vnode 0x%x, cookie 0x%x\n", v
, cookie
));
649 if(v
->stream
.type
== STREAM_TYPE_DIR
)
650 return ERR_VFS_IS_DIR
;
655 //--------------------------------------------------------------------------------
656 static int isofs_freecookie(fs_cookie _fs
, fs_vnode _v
, file_cookie _cookie
)
658 struct isofs_vnode
*v
= _v
;
659 struct isofs_cookie
*cookie
= _cookie
;
661 TOUCH(v
); TOUCH(cookie
);
663 TRACE(("isofs_freecookie: entry vnode 0x%x, cookie 0x%x\n", v
, cookie
));
665 if(v
->stream
.type
== STREAM_TYPE_DIR
)
666 return ERR_VFS_IS_DIR
;
674 //--------------------------------------------------------------------------------
675 #define READ_CHUNK 16384
676 static ssize_t
isofs_read(fs_cookie _fs
, fs_vnode _v
, file_cookie _cookie
,
677 void *buf
, off_t pos
, ssize_t len
)
679 struct isofs
*fs
= _fs
;
680 struct isofs_vnode
*v
= _v
;
681 struct isofs_cookie
*cookie
= _cookie
;
688 TRACE(("isofs_read: vnode 0x%x, cookie 0x%x, pos 0x%x 0x%x, len 0x%x\n", v
, cookie
, pos
, len
));
690 if(v
->stream
.type
== STREAM_TYPE_DIR
)
691 return ERR_VFS_IS_DIR
;
693 // If size is negative, forget it
697 mutex_lock(&fs
->lock
);
699 // If position is negative, we'll read from current pos
701 // we'll read where the cookie is at
702 pos
= cookie
->u
.file
.pos
;
706 // If position is past filelength, forget it
707 if (pos
>= cookie
->s
->data_len
) {
712 // If read goes partially beyond EOF
713 if (pos
+ len
> cookie
->s
->data_len
) {
715 len
= cookie
->s
->data_len
- pos
;
718 tempbuf
= kmalloc(READ_CHUNK
);
724 ssize_t to_read
= (READ_CHUNK
< len
) ? READ_CHUNK
: len
;
725 err
= sys_read(fs
->fd
, tempbuf
, cookie
->s
->data_pos
+ pos
, to_read
);
729 user_memcpy(buf
, tempbuf
, err
);
732 buf
= ((char*)buf
)+err
;
735 // Move to next bit of the file
740 cookie
->u
.file
.pos
= pos
;
743 mutex_unlock(&fs
->lock
);
750 //--------------------------------------------------------------------------------
751 static ssize_t
isofs_write(fs_cookie fs
, fs_vnode _v
, file_cookie cookie
, const void *buf
, off_t pos
, ssize_t len
)
753 struct isofs_vnode
*v
= _v
;
755 TRACE(("isofs_write: vnode 0x%x, cookie 0x%x, pos 0x%x 0x%x, len 0x%x\n", v
, cookie
, pos
, len
));
757 if(v
->stream
.type
== STREAM_TYPE_DIR
)
758 return ERR_VFS_IS_DIR
;
760 return ERR_VFS_READONLY_FS
;
763 //--------------------------------------------------------------------------------
764 static int isofs_seek(fs_cookie _fs
, fs_vnode _v
, file_cookie _cookie
, off_t pos
, seek_type st
)
766 struct isofs
*fs
= _fs
;
767 struct isofs_vnode
*v
= _v
;
768 struct isofs_cookie
*cookie
= _cookie
;
773 TRACE(("isofs_seek: vnode 0x%x, cookie 0x%x, pos 0x%x 0x%x, seek_type %d\n", v
, cookie
, pos
, st
));
775 if(v
->stream
.type
== STREAM_TYPE_DIR
)
776 return ERR_VFS_IS_DIR
;
778 mutex_lock(&fs
->lock
);
784 if(pos
> cookie
->s
->data_len
)
785 pos
= cookie
->s
->data_len
;
786 cookie
->u
.file
.pos
= pos
;
789 if(pos
+ cookie
->u
.file
.pos
> cookie
->s
->data_len
)
790 cookie
->u
.file
.pos
= cookie
->s
->data_len
;
791 else if(pos
+ cookie
->u
.file
.pos
< 0)
792 cookie
->u
.file
.pos
= 0;
794 cookie
->u
.file
.pos
+= pos
;
798 cookie
->u
.file
.pos
= cookie
->s
->data_len
;
799 else if(pos
+ cookie
->s
->data_len
< 0)
800 cookie
->u
.file
.pos
= 0;
802 cookie
->u
.file
.pos
= pos
+ cookie
->s
->data_len
;
805 err
= ERR_INVALID_ARGS
;
809 mutex_unlock(&fs
->lock
);
814 //--------------------------------------------------------------------------------
815 static int isofs_ioctl(fs_cookie _fs
, fs_vnode _v
, file_cookie _cookie
, int op
, void *buf
, size_t len
)
817 TRACE(("isofs_ioctl: vnode 0x%x, cookie 0x%x, op %d, buf 0x%x, len 0x%x\n", _v
, _cookie
, op
, buf
, len
));
819 return ERR_INVALID_ARGS
;
822 //--------------------------------------------------------------------------------
823 static int isofs_canpage(fs_cookie _fs
, fs_vnode _v
)
825 struct isofs_vnode
*v
= _v
;
829 TRACE(("isofs_canpage: vnode 0x%x\n", v
));
834 //--------------------------------------------------------------------------------
835 static ssize_t
isofs_readpage(fs_cookie _fs
, fs_vnode _v
, iovecs
*vecs
, off_t pos
)
837 struct isofs_vnode
*v
= _v
;
841 TRACE(("isofs_readpage: vnode 0x%x, vecs 0x%x, pos 0x%x 0x%x\n", v
, vecs
, pos
));
843 return ERR_NOT_ALLOWED
;
846 //--------------------------------------------------------------------------------
847 static int isofs_create(fs_cookie _fs
, fs_vnode _dir
, const char *name
, void *create_args
, vnode_id
*new_vnid
)
849 return ERR_VFS_READONLY_FS
;
852 //--------------------------------------------------------------------------------
853 static int isofs_unlink(fs_cookie _fs
, fs_vnode _dir
, const char *name
)
855 return ERR_VFS_READONLY_FS
;
858 //--------------------------------------------------------------------------------
859 static int isofs_rename(fs_cookie _fs
, fs_vnode _olddir
, const char *oldname
, fs_vnode _newdir
, const char *newname
)
861 return ERR_VFS_READONLY_FS
;
864 //--------------------------------------------------------------------------------
865 static int isofs_mkdir(fs_cookie _fs
, fs_vnode _base_dir
, const char *name
)
867 return ERR_VFS_READONLY_FS
;
870 //--------------------------------------------------------------------------------
871 static int isofs_rmdir(fs_cookie _fs
, fs_vnode _base_dir
, const char *name
)
873 return ERR_VFS_READONLY_FS
;
876 //--------------------------------------------------------------------------------
877 static ssize_t
isofs_writepage(fs_cookie _fs
, fs_vnode _v
, iovecs
*vecs
, off_t pos
)
879 struct isofs_vnode
*v
= _v
;
883 TRACE(("isofs_writepage: vnode 0x%x, vecs 0x%x, pos 0x%x 0x%x\n", v
, vecs
, pos
));
885 return ERR_NOT_ALLOWED
;
888 //--------------------------------------------------------------------------------
889 static int isofs_rstat(fs_cookie _fs
, fs_vnode _v
, struct file_stat
*stat
)
891 struct isofs
*fs
= _fs
;
892 struct isofs_vnode
*v
= _v
;
895 TRACE(("isofs_rstat: vnode 0x%x (0x%x 0x%x), stat 0x%x\n", v
, v
->id
, stat
));
897 mutex_lock(&fs
->lock
);
900 stat
->type
= v
->stream
.type
;
902 switch(v
->stream
.type
) {
903 case STREAM_TYPE_DIR
:
906 case STREAM_TYPE_FILE
:
907 stat
->size
= v
->stream
.data_len
;
910 err
= ERR_INVALID_ARGS
;
914 mutex_unlock(&fs
->lock
);
919 //--------------------------------------------------------------------------------
920 static int isofs_wstat(fs_cookie _fs
, fs_vnode _v
, struct file_stat
*stat
, int stat_mask
)
922 return ERR_VFS_READONLY_FS
;
925 //================================================================================
926 // REGISTRATION HANDLING
927 //================================================================================
929 static struct fs_calls isofs_calls
= {
930 &isofs_mount
, // mount
931 &isofs_unmount
, // unmount
934 isofs_lookup
, // lookup
936 &isofs_getvnode
, // getvnode
937 &isofs_putvnode
, // putvnode
938 &isofs_removevnode
, // removevnode
940 &isofs_opendir
, // opendir
941 &isofs_closedir
, // closedir
942 &isofs_rewinddir
, // rewinddir
943 &isofs_readdir
, // readdir
946 &isofs_close
, // close
947 &isofs_freecookie
, // freecookie
948 &isofs_fsync
, // fsync
951 &isofs_write
, // write
953 &isofs_ioctl
, // ioctl
955 &isofs_canpage
, // canpage
956 &isofs_readpage
, // readpage
957 &isofs_writepage
, // writepage
959 &isofs_create
, // create
960 &isofs_unlink
, // unlink
961 &isofs_rename
, // rename
963 &isofs_mkdir
, // mkdir
964 &isofs_rmdir
, // rmdir
966 &isofs_rstat
, // rstat
967 &isofs_wstat
// wstat
970 int fs_bootstrap(void);
972 //--------------------------------------------------------------------------------
973 int fs_bootstrap(void)
975 dprintf("bootstrap_isofs: entry\n");
976 return vfs_register_filesystem("isofs", &isofs_calls
);