3 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
4 * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
5 * Copyright (C) 2010 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
32 #include <partition.h>
36 #define EXT2_MAGIC 0xEF53 // magic number for ext2 filesystem
38 #define EXT2_SUPERBLOCK_SECTOR 1 // sector, where is placed superblock
40 #define EXT2_GOOD_OLD_REV 0 // original format
41 #define EXT2_DYNAMIC_REV 1 // V2 format with dynamic inode sizes
43 #define EXT2_BAD_INO 0x01 // bad blocks inode
44 #define EXT2_ROOT_INO 0x02 // root directory inode
45 #define EXT2_ACL_IDX_INO 0x03 // ACL index inode (deprecated?)
46 #define EXT2_ACL_DATA_INO 0x04 // ACL data inode (deprecated?)
47 #define EXT2_BOOT_LOADER_INO 0x05 // boot loader inode
48 #define EXT2_UNDEL_DIR_INO 0x06 // undelete directory inode
50 #define EXT2_S_IFMT 0xF000 // format mask
51 #define EXT2_S_IFSOCK 0xC000 // socket
52 #define EXT2_S_IFLNK 0xA000 // symbolic link
53 #define EXT2_S_IFREG 0x8000 // regular file
54 #define EXT2_S_IFBLK 0x6000 // block device
55 #define EXT2_S_IFDIR 0x4000 // directory
56 #define EXT2_S_IFCHR 0x2000 // character device
57 #define EXT2_S_IFIFO 0x1000 // fifo
59 #define EXT2_S_ISUID 0x0800 // SUID
60 #define EXT2_S_ISGID 0x0400 // SGID
61 #define EXT2_S_ISVTX 0x0200 // sticky bit
62 #define EXT2_S_IRWXU 0x01C0 // user access rights mask
63 #define EXT2_S_IRUSR 0x0100 // read
64 #define EXT2_S_IWUSR 0x0080 // write
65 #define EXT2_S_IXUSR 0x0040 // execute
66 #define EXT2_S_IRWXG 0x0038 // group access rights mask
67 #define EXT2_S_IRGRP 0x0020 // read
68 #define EXT2_S_IWGRP 0x0010 // write
69 #define EXT2_S_IXGRP 0x0008 // execute
70 #define EXT2_S_IRWXO 0x0007 // others access rights mask
71 #define EXT2_S_IROTH 0x0004 // read
72 #define EXT2_S_IWOTH 0x0002 // write
73 #define EXT2_S_IXOTH 0x0001 // execute
75 #define EXT2_FT_UNKNOWN 0
76 #define EXT2_FT_REG_FILE 1
78 #define EXT2_FT_CHRDEV 3
79 #define EXT2_FT_BLKDEV 4
80 #define EXT2_FT_FIFO 5
81 #define EXT2_FT_SOCK 6
82 #define EXT2_FT_SYMLINK 7
88 unsigned r_blockcount
;
89 unsigned free_blockcount
;
90 unsigned free_inodecount
;
91 unsigned first_data_block
;
92 unsigned log_block_size
;
93 unsigned log_frag_size
;
94 unsigned blocks_per_group
;
95 unsigned frags_per_group
;
96 unsigned inodes_per_group
;
99 unsigned short mnt_count
;
100 unsigned short max_mnt_count
;
101 unsigned short magic
;
102 unsigned short state
;
103 unsigned short errors
;
104 unsigned short minor_rev_level
;
106 unsigned checkinterval
;
109 unsigned short def_resuid
;
110 unsigned short def_resgid
;
111 // -- EXT2_DYNAMIC_REV Specific --
113 unsigned short inode_size
;
114 unsigned short block_group_nr
;
115 unsigned feature_compat
;
116 unsigned feature_incompat
;
117 unsigned feature_ro_compat
;
118 unsigned char uuid
[16];
119 unsigned char volume_name
[16];
120 unsigned char last_mounted
[64];
121 unsigned algo_bitmap
;
122 // -- Performance Hints --
123 unsigned char prealloc_blocks
;
124 unsigned char prealloc_dir_blocks
;
125 unsigned short alignment
;
126 // -- Journaling Support --
127 unsigned char journal_uuid
[16];
128 unsigned journal_inum
;
129 unsigned journal_dev
;
130 unsigned last_orphan
;
132 unsigned char padding
[788];
136 unsigned block_bitmap
;
137 unsigned inode_bitmap
;
138 unsigned inode_table
;
139 unsigned short free_blocks_count
;
140 unsigned short free_inodes_count
;
141 unsigned short used_dirs_count
;
143 unsigned char reserved
[12];
155 unsigned short links_count
;
164 unsigned char osd2
[12];
169 unsigned short rec_len
;
170 unsigned char name_len
;
171 unsigned char file_type
;
172 unsigned char name
[255];
175 static unsigned block_size
= 0;
176 static unsigned block_free
= 0;
177 static unsigned inode_curr
= 0;
179 ext2_superblock_t
*superblock
;
181 unsigned ext2_sector_read (partition_t
*p
, unsigned sector
, unsigned char *buffer
)
183 /* ext2 sector is 1kB length */
184 unsigned address
= sector
* 2;
186 /* lba28_drive_read () read 512 bytes from drive 2 times +512 bytes */
187 lba28_drive_read (p
, address
+p
->sector_start
, (unsigned char *) buffer
);
188 lba28_drive_read (p
, address
+p
->sector_start
+1, (unsigned char *) buffer
+512);
193 unsigned ext2_sector_write (partition_t
*p
, unsigned sector
, unsigned char *buffer
)
195 /* ext2 sector is 1kB length */
196 unsigned address
= sector
* 2;
198 /* lba28_drive_write () write 512 bytes to drive 2 times +512 bytes */
199 lba28_drive_write (p
, address
+p
->sector_start
, (unsigned char *) buffer
);
200 lba28_drive_write (p
, address
+p
->sector_start
+1, (unsigned char *) buffer
+512);
205 extern unsigned long file_cache_id
;
206 /* read data block of file by inode */
207 unsigned ext2_block_read (partition_t
*p
, ext2_inode_t
*inode
, vfs_content_t
*content
)
209 unsigned address
= inode
->block
[0] * 2 + p
->sector_start
;
210 unsigned long len
= 0;
213 DPRINT (DBG_DRIVER
| DBG_FS
, "blocks: %d %d %d %d %d %d %d %d %d %d", inode
->block
[0], inode
->block
[1], inode
->block
[2], inode
->block
[3], inode
->block
[4], inode
->block
[5], inode
->block
[6], inode
->block
[12], inode
->block
[13], inode
->block
[14]);
215 char *block
= (char *) kmalloc (1024);
217 unsigned block_new
[15];
219 if (inode
->block
[12]) {
220 ext2_sector_read (p
, inode
->block
[12], block
);
222 memcpy (&block_new
, block
, sizeof (unsigned) * 15);
225 cache_t
*cache
= cache_create (0, inode
->size
, 1);
231 /* first 12 address are direct and next are from indirect block */
233 address
= inode
->block
[i
];
235 address
= block_new
[i
-12];
240 /* read 1024 bytes block and put data to file_cache */
241 ext2_sector_read (p
, address
, (unsigned char *) block
);
249 if ((inode
->size
- len
) > 1024)
250 cache_add (block
, 1024);
252 cache_add (block
, inode
->size
- len
);
254 if ((len
+1024) > inode
->size
)
263 content
->ptr
= (char *) &cache
->data
;
264 content
->len
= cache
->limit
;
269 /* write data block of file by inode */
270 unsigned ext2_block_write (partition_t
*p
, ext2_inode_t
*inode
)
272 /* when it is new file, lets assign free data block */
273 if (!inode
->block
[0])
274 inode
->block
[0] = 10000;
277 unsigned address
= inode
->block
[0] * 2 + p
->sector_start
;
278 unsigned long len
= 0;
281 cache_t
*cache
= cache_read ();
284 printf ("ext2 -> nothing to write\n");
289 /* write 512 bytes block from file_cache */
290 lba28_drive_write (p
, address
+i
, &cache
->data
+len
);
292 if ((len
+512) > cache
->limit
)
299 inode
->size
= cache
->limit
;
304 /* return inode structure by inode id number */
305 ext2_inode_t
*ext2_inode_read (partition_t
*p
, char *block
, unsigned id
)
307 /* group descriptors */
309 ext2_group_t
*group
= (ext2_group_t
*) &buf
;//kmalloc (1024);
314 ext2_sector_read (p
, 2, (unsigned char *) group
);
316 /* locate inode group and structure */
317 unsigned group_num
= (id
- 1) / superblock
->inodes_per_group
;
318 unsigned id_new
= (id
- 1) % superblock
->inodes_per_group
;
320 ext2_sector_read (p
, group
[group_num
].inode_table
, (unsigned char *) block
);
322 ext2_inode_t
*inode
= (ext2_inode_t
*) block
;
324 DPRINT (DBG_DRIVER
| DBG_FS
, "inode -> %d / %d - 0x%x - %d - %d - %d", superblock
->inodes_per_group
, id_new
, inode
[id_new
].mode
, inode
[id_new
].ctime
, inode
[id_new
].size
, inode
[id_new
].block
[0]);
328 return &inode
[id_new
];
331 /* write inode structure by inode id number */
332 unsigned ext2_inode_write (partition_t
*p
, ext2_inode_t
*inode
, unsigned id
)
334 /* group descriptors */
335 ext2_group_t
*group
= (ext2_group_t
*) kmalloc (1024);
340 ext2_sector_read (p
, 2, (unsigned char *) group
);
342 /* locate inode group and structure */
343 unsigned group_num
= (id
- 1) / superblock
->inodes_per_group
;
344 unsigned id_new
= (id
- 1) % superblock
->inodes_per_group
;
346 ext2_inode_t
*block
= (ext2_inode_t
*) kmalloc (1024);
353 ext2_sector_read (p
, group
[group_num
].inode_table
, (unsigned char *) block
);
355 memcpy (&block
[id_new
], inode
, sizeof (ext2_inode_t
));
357 ext2_sector_write (p
, group
[group_num
].inode_table
, (unsigned char *) block
);
359 //DPRINT (DBG_DRIVER | DBG_FS, "inode -> %d / %d - 0x%x - %d - %d - %d", superblock->inodes_per_group, id_new, inode[id_new].mode, inode[id_new].ctime, inode[id_new].size, inode[id_new].block[0]);
367 /* scan current directory and assign to dir[] structure */
368 unsigned ext2_dir_scan (partition_t
*p
, ext2_inode_t
*inode
)
371 ext2_dir_t
*ext2dir
= (ext2_dir_t
*) &buf
;//kmalloc (1024);
376 /* read direct block */
377 ext2_sector_read (p
, inode
->block
[0], (unsigned char *) ext2dir
);
379 unsigned dir_next
= 0;
383 ext2_dir_t
*dir_new
= (ext2_dir_t
*) ((void *) ext2dir
+ dir_next
);
385 DPRINT (DBG_DRIVER
| DBG_FS
, "dir -> 0x%x : %d - %d - %d - %s - %d", dir_new
, dir_new
->inode
, dir_new
->rec_len
, dir_new
->name_len
, dir_new
->name
, dir_new
->file_type
);
387 if (!dir_new
->rec_len
|| !dir_new
->inode
|| dir_next
>= 1024)
390 /* we won't unknown file type */
391 if (dir_new
->file_type
== EXT2_FT_UNKNOWN
) {
392 dir_next
+= dir_new
->rec_len
;
396 /* yeah :( .. limit to 10 characters for dir[] entry */
397 if (dir_new
->name_len
< 10) {
398 memcpy (dir
[entry
].name
, dir_new
->name
, dir_new
->name_len
);
399 dir
[entry
].name
[dir_new
->name_len
] = '\0';
401 memcpy (dir
[entry
].name
, dir_new
->name
, 9);
402 dir
[entry
].name
[9] = '\0';
405 /* check for directory type or file */
406 if (dir_new
->file_type
== EXT2_FT_DIR
)
411 /* increase dir_next with current record length for find next ext2_dir_t * structure */
412 dir_next
+= dir_new
->rec_len
;
413 /* increase dir[] entry */
419 /* clear last+1 entry of dir[] for prevent */
420 memset (dir
[entry
].name
, 0, 10);
425 unsigned ext2_create_entity (partition_t
*p
, char *name
, unsigned char type
)
430 char *block
= (char *) kmalloc (1024);
435 DPRINT (DBG_DRIVER
| DBG_FS
, "ext2_create_entity -> %d : %s", inode_curr
, name
);
437 /* read inode structure by current inode id number */
438 ext2_inode_t
*inode
= ext2_inode_read (p
, block
, inode_curr
);
445 ext2_dir_t
*ext2dir
= (ext2_dir_t
*) kmalloc (1024);
452 /* read direct block */
453 ext2_sector_read (p
, inode
->block
[0], (unsigned char *) ext2dir
);
455 unsigned dir_next
= 0;
458 ext2_dir_t
*dir_new
= (ext2_dir_t
*) ((char *) ext2dir
+ dir_next
);
460 if (dir_new
->rec_len
&& dir_new
->inode
) {
461 dir_next
+= dir_new
->rec_len
;
462 printf ("dir_next: %d | %d | %d\n", dir_next
, dir_new
->rec_len
, dir_new
->inode
);
464 if (dir_next
>= 1024) {
465 if (dir_new
->rec_len
< 264) {
466 printf ("ERROR -> out of dirent\n");
470 dir_next
-= dir_new
->rec_len
;
471 dir_new
->rec_len
= (dir_new
->name_len
+9) <= 12 ? 12 : 20;
472 dir_next
+= dir_new
->rec_len
;
473 printf ("dir_new->rec_len: %d dir_next: %d\n", dir_new
->rec_len
, dir_next
);
475 int inode
= dir_new
->inode
+ 1;
477 if (type
== EXT2_FT_DIR
)
480 dir_new
= (ext2_dir_t
*) ((char *) ext2dir
+ dir_next
);
482 dir_new
->inode
= inode
;
487 /* set the file type */
488 dir_new
->file_type
= type
;
490 unsigned name_len
= strlen (name
);
495 /* yeah :( .. limit to 10 characters for dir[] entry */
496 memcpy (dir_new
->name
, name
, name_len
);
497 dir_new
->name_len
= name_len
;
498 dir_new
->rec_len
= 1024 - dir_next
;
500 ext2_inode_t
*inode_new
= (ext2_inode_t
*) kmalloc (sizeof (ext2_inode_t
));
505 tm
*t
= rtc_getcurrtime ();
510 inode_new
->atime
= t
->__tm_gmtoff
;
511 inode_new
->ctime
= t
->__tm_gmtoff
;
512 inode_new
->mtime
= t
->__tm_gmtoff
;
513 inode_new
->dtime
= 0;
515 inode_new
->links_count
= 0;
516 inode_new
->blocks
= 0;
517 inode_new
->flags
= 0;
520 if (dir_new
->file_type
!= EXT2_FT_DIR
)
521 inode_new
->block
[0] = block_free
;
523 inode_new
->block
[0] = 0;
525 if (!ext2_inode_write (p
, inode_new
, dir_new
->inode
)) {
532 /* write direct block */
533 ext2_sector_write (p
, inode
->block
[0], (unsigned char *) ext2dir
);
537 DPRINT (DBG_DRIVER
| DBG_FS
, "dir -> dir_new->inode: %d | %d | %d", dir_new
->inode
, dir_new
->rec_len
, sizeof (ext2_inode_t
));
546 //DPRINT (DBG_DRIVER | DBG_FS, "dir -> %d - %d %d %d %d %d\n", inode_new->size, inode_new->block[0], inode_new->block[1], inode_new->block[2], inode_new->block[13], inode_new->block[14]);
548 /* write chunk of data */
549 //ext2_block_write (p, inode_new);
560 unsigned ext2_cd_root (partition_t
*p
)
562 /* group descriptors */
564 ext2_group_t
*group
= (ext2_group_t
*) &buf
; //kmalloc (1024);
569 /* read group decriptor */
570 ext2_sector_read (p
, 2, (unsigned char *) group
);
572 DPRINT (DBG_DRIVER
| DBG_FS
, "group -> %d - %d - %d", group
[0].block_bitmap
, group
[0].inode_bitmap
, group
[0].inode_table
);
575 ext2_inode_t
*inode
= (ext2_inode_t
*) kmalloc (1024);
580 /* read root inode */
581 ext2_sector_read (p
, group
[0].inode_table
, (unsigned char *) inode
);
583 DPRINT (DBG_DRIVER
| DBG_FS
, "inode -> 0x%x - %d - %d - %d", inode
[1].mode
, inode
[1].ctime
, inode
[1].size
, inode
[1].block
[0]);
585 /* read dir entries from root inode */
586 ext2_dir_scan (p
, &inode
[EXT2_ROOT_INO
-1]);
588 inode_curr
= EXT2_ROOT_INO
;
596 unsigned ext2_cd (partition_t
*p
, char *name
)
599 char *block
= (char *) &buf
;// kmalloc (1024);
604 /* read inode structure by current inode id number */
605 ext2_inode_t
*inode
= ext2_inode_read (p
, block
, inode_curr
);
612 ext2_dir_t
*ext2dir
= (ext2_dir_t
*) kmalloc (1024);
619 /* read direct block by inode */
620 ext2_sector_read (p
, inode
->block
[0], (unsigned char *) ext2dir
);
622 unsigned dir_next
= 0;
624 unsigned name_len
= strlen (name
);
626 /* loop for find name of directory, where we want go */
628 ext2_dir_t
*dir_new
= (ext2_dir_t
*) ((void *) ext2dir
+ dir_next
);
630 if (!dir_new
->rec_len
|| !dir_new
->inode
|| dir_next
>= 1024)
633 DPRINT (DBG_DRIVER
| DBG_FS
, "dir -> 0x%x : %d - %d - %d - %s", dir_new
, dir_new
->inode
, dir_new
->rec_len
, dir_new
->name_len
, dir_new
->name
);
635 /* is it really directory ? */
636 if (dir_new
->file_type
== EXT2_FT_DIR
)
637 if (!strncmp (name
, dir_new
->name
, name_len
)) {
638 /* we've found inode of directory, what we need. Let's get this inode structure */
639 ext2_inode_t
*inode_new
= ext2_inode_read (p
, block
, dir_new
->inode
);
641 DPRINT (DBG_DRIVER
| DBG_FS
, "dir -> dir_new->inode: %d", dir_new
->inode
);
646 inode_curr
= dir_new
->inode
;
648 DPRINT (DBG_DRIVER
| DBG_FS
, "dir -> %d %d %d %d %d", inode_new
->block
[0], inode_new
->block
[1], inode_new
->block
[2], inode_new
->block
[13], inode_new
->block
[14]);
650 /* assign new content to dir[] structure */
651 ext2_dir_scan (p
, inode_new
);
656 dir_next
+= dir_new
->rec_len
;
667 unsigned ext2_cat (partition_t
*p
, char *name
, vfs_content_t
*content
)
669 char *block
= (char *) kmalloc (1024);
674 DPRINT (DBG_DRIVER
| DBG_FS
, "cat -> %d", inode_curr
);
676 /* read inode structure by current inode id number */
677 ext2_inode_t
*inode
= ext2_inode_read (p
, block
, inode_curr
);
684 ext2_dir_t
*ext2dir
= (ext2_dir_t
*) kmalloc (1024);
691 /* read direct block */
692 ext2_sector_read (p
, inode
->block
[0], (unsigned char *) ext2dir
);
694 unsigned dir_next
= 0;
695 unsigned name_len
= strlen (name
);
698 ext2_dir_t
*dir_new
= (ext2_dir_t
*) ((void *) ext2dir
+ dir_next
);
700 if (!dir_new
->rec_len
|| !dir_new
->inode
|| dir_next
>= 1024)
703 /* check for file type - regular file */
704 if (dir_new
->file_type
== EXT2_FT_REG_FILE
)
705 if (!strncmp (name
, dir_new
->name
, name_len
)) {
706 ext2_inode_t
*inode_new
= ext2_inode_read (p
, block
, dir_new
->inode
);
708 DPRINT (DBG_DRIVER
| DBG_FS
, "dir -> dir_new->inode: %d", dir_new
->inode
);
713 DPRINT (DBG_DRIVER
| DBG_FS
, "dir -> %d - %d %d %d %d %d", inode_new
->size
, inode_new
->block
[0], inode_new
->block
[1], inode_new
->block
[2], inode_new
->block
[13], inode_new
->block
[14]);
715 /* when file is not clear and direct block is available,
717 if (inode_new
->size
&& inode_new
->block
[0])
718 ext2_block_read (p
, inode_new
, content
);
723 dir_next
+= dir_new
->rec_len
;
733 unsigned ext2_write_file (partition_t
*p
, char *name
)
735 char *block
= (char *) kmalloc (1024);
740 DPRINT (DBG_DRIVER
| DBG_FS
, "write_file -> %d", inode_curr
);
742 /* read inode structure by current inode id number */
743 ext2_inode_t
*inode
= ext2_inode_read (p
, block
, inode_curr
);
750 ext2_dir_t
*ext2dir
= (ext2_dir_t
*) kmalloc (1024);
757 /* read direct block */
758 ext2_sector_read (p
, inode
->block
[0], (unsigned char *) ext2dir
);
760 unsigned dir_next
= 0;
761 unsigned name_len
= strlen (name
);
764 ext2_dir_t
*dir_new
= (ext2_dir_t
*) ((void *) ext2dir
+ dir_next
);
766 if (!dir_new
->rec_len
|| !dir_new
->inode
|| dir_next
>= 1024)
769 /* check for file type - regular file */
770 if (dir_new
->file_type
== EXT2_FT_REG_FILE
)
771 if (!strncmp (name
, dir_new
->name
, name_len
)) {
772 ext2_inode_t
*inode_new
= ext2_inode_read (p
, block
, dir_new
->inode
);
774 DPRINT (DBG_DRIVER
| DBG_FS
, "dir -> dir_new->inode: %d", dir_new
->inode
);
779 DPRINT (DBG_DRIVER
| DBG_FS
, "dir -> %d - %d %d %d %d %d", inode_new
->size
, inode_new
->block
[0], inode_new
->block
[1], inode_new
->block
[2], inode_new
->block
[13], inode_new
->block
[14]);
781 /* write chunk of data */
782 ext2_block_write (p
, inode_new
);
787 dir_next
+= dir_new
->rec_len
;
797 unsigned mkext2 (partition_t
*p
)
803 superblock
= (ext2_superblock_t
*) kmalloc (sizeof (ext2_superblock_t
));
808 superblock
->inodecount
= 2;
809 //superblock->uuid = ;
810 superblock
->magic
= EXT2_MAGIC
;
811 superblock
->inode_size
= 128;
812 superblock
->log_block_size
= 0;
813 superblock
->first_ino
= 2;
814 superblock
->rev_level
= 0;
815 superblock
->inodes_per_group
= 1832;
817 /* write superblock from drive on first sector */
818 ext2_sector_write (p
, EXT2_SUPERBLOCK_SECTOR
, (unsigned char *) superblock
);
820 DPRINT (DBG_DRIVER
| DBG_FS
, "superblock -> %d, %d - %s - %x - %d", sizeof (ext2_superblock_t
), superblock
->inodecount
, superblock
->uuid
, superblock
->magic
, superblock
->inode_size
);
822 /* check ext2 magic number */
823 if (superblock
->magic
!= EXT2_MAGIC
) {
828 /* read block size (default is 1024) */
829 block_size
= 1024 << superblock
->log_block_size
;
831 DPRINT (DBG_DRIVER
| DBG_FS
, "superblock -> %d - %d - %d - %d", block_size
, superblock
->first_ino
, superblock
->rev_level
, superblock
->inodes_per_group
);
834 /* group descriptors */
835 ext2_group_t
*group
= (ext2_group_t
*) kmalloc (1024);
840 /* read group decriptor */
841 ext2_sector_write (p
, 2, (unsigned char *) group
);
843 DPRINT (DBG_DRIVER
| DBG_FS
, "group -> %d - %d - %d", group
[0].block_bitmap
, group
[0].inode_bitmap
, group
[0].inode_table
);
846 ext2_inode_t
*inode
= (ext2_inode_t
*) kmalloc (1024);
851 /* read root inode */
852 ext2_sector_read (p
, group
[0].inode_table
, (unsigned char *) inode
);
854 DPRINT (DBG_DRIVER
| DBG_FS
, "inode -> 0x%x - %d - %d - %d", inode
[1].mode
, inode
[1].ctime
, inode
[1].size
, inode
[1].block
[0]);
856 /* read dir entries from root inode */
857 ext2_dir_scan (p
, &inode
[EXT2_ROOT_INO
-1]);
859 inode_curr
= EXT2_ROOT_INO
;
867 unsigned ext2_init (partition_t
*p
)
872 superblock
= (ext2_superblock_t
*) kmalloc (sizeof (ext2_superblock_t
));
877 /* read superblock from drive on first sector */
878 ext2_sector_read (p
, EXT2_SUPERBLOCK_SECTOR
, (unsigned char *) superblock
);
880 DPRINT (DBG_DRIVER
| DBG_FS
, "superblock -> %d, %d - %s - %x - %d", sizeof (ext2_superblock_t
), superblock
->inodecount
, superblock
->uuid
, superblock
->magic
, superblock
->inode_size
);
882 /* check ext2 magic number */
883 if (superblock
->magic
!= EXT2_MAGIC
) {
888 /* read block size (default is 1024) */
889 block_size
= 1024 << superblock
->log_block_size
;
893 DPRINT (DBG_DRIVER
| DBG_FS
, "superblock -> %d - %d - %d - %d", block_size
, superblock
->first_ino
, superblock
->rev_level
, superblock
->inodes_per_group
);
898 bool ext2_handler (unsigned act
, char *block
, unsigned n
, unsigned long l
)
903 return (bool) ext2_init ((partition_t
*) block
);
908 return (bool) ext2_cat (curr_part
, dir
[n
].name
, (vfs_content_t
*) block
);
913 ext2_write_file (curr_part
, dir
[n
].name
);
920 /* root directory - mount action*/
922 return (bool) ext2_cd_root (curr_part
);
924 /* walk to another directory */
925 return (bool) ext2_cd (curr_part
, block
);
930 return ext2_create_entity (curr_part
, block
, EXT2_FT_DIR
);
935 return ext2_create_entity (curr_part
, block
, EXT2_FT_REG_FILE
);