Cleanup in elf.c with .bss section clean; adm command mounts cdrom instead of floppy...
[ZeXOS.git] / kernel / drivers / fs / zexfs.c
blob9c1472b960df4db8318fc2ede2c7a638bfae9022
1 /*
2 * ZeX/OS
3 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
4 * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include <config.h>
22 #include <build.h>
24 #ifdef ARCH_i386
26 #include <system.h>
27 #include <string.h>
28 #include <dev.h>
29 #include <fs.h>
30 #include <partition.h>
31 #include <cache.h>
32 #include <vfs.h>
34 #define ZEXFS_INITBLOCK_SECTOR 63
35 #define ZEXFS_DIRENT_SECTOR 64
36 #define ZEXFS_IDIRENT_SECTOR ZEXFS_DIRENT_SECTOR+30
37 #define ZEXFS_BLKENT_SECTOR 1024
38 #define ZEXFS_IBLKENT_SECTOR 2048
40 #define ZEXFS_DIRENT_PREALLOC 512 /* you can create # new dirents in fs */
41 #define ZEXFS_BLKENT_PREALLOC 512 /* you can create # new blkents in fs */
43 #define ZEXFS_DIRENT_FREE 0x0
44 #define ZEXFS_DIRENT_DIR 0x1
45 #define ZEXFS_DIRENT_FILE 0x2
47 #define ZEXFS_BLKENT_FREE 0x0
48 #define ZEXFS_BLKENT_USED 0x1
50 #define __PACKED__ __attribute__ ((__packed__))
52 /* zexos filesystem structures */
53 typedef struct {
54 /* main variables of this ent */
55 unsigned char magic[5]; /* Magic ID of zexfs */
56 unsigned short dirents; /* Count of created dirents */
57 unsigned short blkents; /* Count of created blkents */
58 } zexfs_infoblock;
60 typedef struct {
61 /* main variables of this ent */
62 unsigned char flags; /* Flags for this ent */
64 unsigned short parent; /* Parent node */
65 short children; /* Children node */
67 /* time stamp */
68 unsigned char tm_sec; /* Seconds. [0-60] (1 leap second) */
69 unsigned char tm_min; /* Minutes. [0-59] */
70 unsigned char tm_hour; /* Hours. [0-23] */
71 unsigned char tm_mday; /* Day. [1-31] */
72 unsigned char tm_mon; /* Month. [0-11] */
73 unsigned char tm_year; /* Year = 2000 + tm_year */
75 unsigned char name[21];
76 } __PACKED__ zexfs_dirent;
78 typedef struct {
79 unsigned short next;
80 unsigned short len;
81 } __PACKED__ zexfs_blk_header;
83 /* zexos filesystem structure */
84 typedef struct {
85 zexfs_infoblock iblock;
87 unsigned char *dirents;
88 unsigned char *blkents;
90 unsigned char cache[512];
92 unsigned short node_curr;
93 unsigned short node_prev;
94 } zexfs_t;
96 zexfs_t zexfs;
98 /* clear and pre-set dir[] structure */
99 void zexfs_dir_flush ()
101 unsigned i = 0;
103 // if (zexfs.node_curr != 0) {
104 // printf ("eyk\n");
105 // }
107 for (; i < 223; i ++)
108 memset (dir[i].name, 0, 10);
111 /* read 1024 byte block */
112 unsigned zexfs_block_read (partition_t *p, unsigned sector, unsigned char *block)
114 lba28_drive_read (p, sector, (unsigned char *) block);
115 lba28_drive_read (p, sector+1, (unsigned char *) block+512);
117 return 1;
120 int zexfs_blkent_create (partition_t *p)
122 unsigned i;
123 unsigned y = 0;
125 /* find free dirent in array */
126 for (i = 0; i < zexfs.iblock.blkents + ZEXFS_BLKENT_PREALLOC; i ++) {
127 if (zexfs.blkents[i] == ZEXFS_BLKENT_FREE) {
128 /* match dirent as file or directory */
129 zexfs.blkents[i] = ZEXFS_BLKENT_USED;
131 lba28_drive_write (p, ZEXFS_BLKENT_SECTOR+y, zexfs.blkents+(i/512));
133 /* increase dirents count in infoblock structure */
134 zexfs.iblock.blkents ++;
136 /* update initblock on drive */
137 memset (zexfs.cache+sizeof (zexfs.iblock), 0, 512-sizeof (zexfs.iblock));
138 memcpy (zexfs.cache, &zexfs.iblock, sizeof (zexfs.iblock));
139 lba28_drive_write (p, ZEXFS_INITBLOCK_SECTOR, (unsigned char *) zexfs.cache);
141 DPRINT (DBG_DRIVER | DBG_FS, "ZeXFS -> blkent %d:%d created", i, zexfs.iblock.blkents);
143 return i;
147 kprintf ("ZeXFS -> Sorry, but your filesystem blkent table is full, please reboot or delete some files for correct the problem\n");
150 /* function for write data of file */
151 unsigned zexfs_write_file (partition_t *p, unsigned char *name, vfs_content_t *content)
153 unsigned y = 0;
154 unsigned x = -1;
155 int z = -1;
156 unsigned i = 0;
157 unsigned s = 0;
158 int ret = 0;
159 zexfs_dirent *dirent = 0;
161 for (i = 0; i < zexfs.iblock.dirents + ZEXFS_DIRENT_PREALLOC; i ++) {
162 if (zexfs.dirents[i] != ZEXFS_DIRENT_FREE) {
163 s = i * sizeof (zexfs_dirent);
165 y = s/512;
167 /* read data from sector to cache */
168 if (x != y)
169 lba28_drive_read (p, ZEXFS_IDIRENT_SECTOR+y, zexfs.cache);
171 unsigned char *l = zexfs.cache + (s-(y*512));
172 dirent = (zexfs_dirent *) l;
174 if (zexfs.node_curr == dirent->parent) {
175 // kprintf ("cd_root: %d : %s\n", (s-(y*512)), dirent->name);
177 if (!strcmp (dirent->name, name)) {
178 z = dirent->children;
179 ret = 1;
180 // kprintf ("z: %d: %d\n", z, y);
181 break;
185 x = y;
189 if (!ret) {
190 kprintf ("ZeXFS -> file %s not found\n", name);
191 return 0;
194 /* is file block already created ? */
195 if (z == -1) {
196 z = zexfs_blkent_create (p);
198 if (z == -1) {
199 kprintf ("ZeXFS -> Drive is full\n");
200 return 0;
203 lba28_drive_read (p, ZEXFS_IDIRENT_SECTOR+y, zexfs.cache);
205 dirent->children = z;
206 /* in memory just rewrite dirent structure */
207 memcpy (zexfs.cache+(s-(y*512)), (void *) dirent, sizeof (zexfs_dirent));
209 /* write new data from cache */
210 lba28_drive_write (p, ZEXFS_IDIRENT_SECTOR+y, zexfs.cache);
213 zexfs_blk_header blk;
215 unsigned l;
216 int z2 = z;
217 for (l = 0; l < content->len; l += (512-sizeof (zexfs_blk_header))) {
218 blk.next = (content->len > (l + (512-sizeof (zexfs_blk_header)))) ? 1 : 0;
220 if (blk.next) {
221 blk.next = zexfs_blkent_create (p) - z2;
222 blk.len = 512-sizeof (zexfs_blk_header);
223 } else
224 blk.len = content->len - l;
225 //kprintf ("next: %d | %d | %d | %d\n", blk.next, ZEXFS_IBLKENT_SECTOR, z, l);
227 memcpy (zexfs.cache, &blk, sizeof (zexfs_blk_header));
228 memcpy (zexfs.cache+sizeof (zexfs_blk_header), content->ptr+l, 512-sizeof (zexfs_blk_header));
230 lba28_drive_write (p, ZEXFS_IBLKENT_SECTOR+z+l, zexfs.cache);
231 z2 = z;
234 return 1;
237 /* function for read data of file */
238 unsigned zexfs_read_file (partition_t *p, unsigned char *name, vfs_content_t *content)
240 unsigned y = 0;
241 unsigned x = -1;
242 int z = -1;
243 unsigned i = 0;
244 unsigned s = 0;
245 int ret = 0;
246 zexfs_dirent *dirent = 0;
248 for (i = 0; i < zexfs.iblock.dirents + ZEXFS_DIRENT_PREALLOC; i ++) {
249 if (zexfs.dirents[i] != ZEXFS_DIRENT_FREE) {
250 s = i * sizeof (zexfs_dirent);
252 y = s/512;
254 /* read data from sector to cache */
255 if (x != y)
256 lba28_drive_read (p, ZEXFS_IDIRENT_SECTOR+y, zexfs.cache);
258 unsigned char *l = zexfs.cache + (s-(y*512));
259 dirent = (zexfs_dirent *) l;
261 if (zexfs.node_curr == dirent->parent) {
262 // kprintf ("cd_root: %d : %s\n", (s-(y*512)), dirent->name);
264 if (!strcmp (dirent->name, name)) {
265 z = dirent->children;
266 ret = 1;
267 break;
271 x = y;
275 if (!ret) {
276 kprintf ("ZeXFS -> file %s not found\n", name);
277 return 0;
280 /* is file block already created ? */
281 if (z == -1) {
282 kprintf ("ZeXFS -> file %s is empty\n", name);
283 return 0;
286 zexfs_blk_header *blk = (zexfs_blk_header *) &zexfs.cache;
288 cache_t *cache = cache_create (0, 0, 0);
290 if (!cache)
291 return 0;
293 unsigned l;
295 for (l = 0; ; l += (512-sizeof (zexfs_blk_header))) {
296 lba28_drive_read (p, ZEXFS_IBLKENT_SECTOR+z+l, zexfs.cache);
298 z += blk->next;
300 cache_add (zexfs.cache+sizeof (zexfs_blk_header), blk->len);
302 if (!blk->next)
303 break;
306 content->ptr = (char *) &cache->data;
307 content->len = cache->limit;
309 return 1;
313 /* NOTE: I dont want to use realloc, so we use preallocated memory block for new dirents */
314 int zexfs_dirent_create (partition_t *p, zexfs_dirent *dirent)
316 unsigned i;
317 unsigned y = 0;
319 /* find free dirent in array */
320 for (i = 0; i < zexfs.iblock.dirents + ZEXFS_DIRENT_PREALLOC; i ++) {
321 if (zexfs.dirents[i] == ZEXFS_DIRENT_FREE) {
322 /* match dirent as file or directory */
323 zexfs.dirents[i] = dirent->flags & ZEXFS_DIRENT_FILE ? ZEXFS_DIRENT_FILE : ZEXFS_DIRENT_DIR;
325 lba28_drive_write (p, ZEXFS_DIRENT_SECTOR+y, zexfs.dirents+(i/512));
327 /* increase dirents count in infoblock structure */
328 zexfs.iblock.dirents ++;
330 /* update initblock on drive */
331 memset (zexfs.cache+sizeof (zexfs.iblock), 0, 512-sizeof (zexfs.iblock));
332 memcpy (zexfs.cache, &zexfs.iblock, sizeof (zexfs.iblock));
333 lba28_drive_write (p, ZEXFS_INITBLOCK_SECTOR, (unsigned char *) zexfs.cache);
335 DPRINT (DBG_DRIVER | DBG_FS, "ZeXFS -> dirent %d:%d created", i, zexfs.iblock.dirents);
337 return i;
341 kprintf ("ZeXFS -> Sorry, but your filesystem dirent table is full, please reboot or delete some files for correct the problem\n");
343 return -1;
346 int zexfs_dirent_find (partition_t *p, zexfs_dirent *mydirent, unsigned char *name)
348 unsigned i;
349 unsigned y = 0;
350 unsigned x = -1;
352 /* find free dirent in array */
353 for (i = 0; i < zexfs.iblock.dirents + ZEXFS_DIRENT_PREALLOC; i ++) {
354 if (zexfs.dirents[i] & ZEXFS_DIRENT_DIR) {
355 unsigned s = i * sizeof (zexfs_dirent);
357 y = s/512;
359 /* read data from sector to cache */
360 if (x != y)
361 lba28_drive_read (p, ZEXFS_IDIRENT_SECTOR+y, zexfs.cache);
363 unsigned char *l = zexfs.cache + (s-(y*512));
364 zexfs_dirent *dirent = (zexfs_dirent *) l;
366 /* we need find same parent node as current node */
367 if (dirent->parent == zexfs.node_curr)
368 if (!strcmp (name, dirent->name)) { /* verify name of dirent with searched name */
369 /* copy structure from founded dirent to our dirent structure */
370 memcpy (&mydirent, &dirent, sizeof (zexfs_dirent));
371 return i;
374 x = y;
378 return -1;
381 int zexfs_dirent_findbynode (partition_t *p, zexfs_dirent *mydirent, unsigned short node)
383 unsigned i = node;
384 unsigned y = 0;
386 if (i > zexfs.iblock.dirents + ZEXFS_DIRENT_PREALLOC)
387 return -1;
389 if (zexfs.dirents[i] == ZEXFS_DIRENT_FREE)
390 return -1;
392 unsigned s = i * sizeof (zexfs_dirent);
394 y = s/512;
396 /* read data from sector to cache */
397 lba28_drive_read (p, ZEXFS_IDIRENT_SECTOR+y, zexfs.cache);
398 //kprintf ("r: %d\n", s-(y*512));
399 unsigned char *l = zexfs.cache + (s-(y*512));
400 zexfs_dirent *dirent = (zexfs_dirent *) l;
402 /* copy structure from founded dirent to our dirent structure */
403 memcpy (mydirent, dirent, sizeof (zexfs_dirent));
405 return 0;
408 /* function for create blank file or directory */
409 unsigned zexfs_create_entity (partition_t *p, unsigned char *name, unsigned flags)
411 zexfs_dirent dirent;
413 memset (&dirent, 0, sizeof (zexfs_dirent));
415 dirent.flags |= flags;
416 dirent.parent = zexfs.node_curr;
418 if (flags & ZEXFS_DIRENT_FILE)
419 dirent.children = -1;
421 unsigned l = strlen (name);
422 memcpy (dirent.name, name, l);
423 dirent.name[l] = '\0';
425 int r = zexfs_dirent_create (p, &dirent);
427 if (r == -1)
428 return 0;
430 r *= sizeof (zexfs_dirent);
432 unsigned x = r/512; /* sizeof (zexfs_dirent) must be dividable by sector size */
434 // kprintf ("he: %d .. %d .. %d\n", x, r, r-(x*512));
436 unsigned i;
437 for (i = 0; i < 223; i ++)
438 if (!dir[i].name[0])
439 break;
441 strcpy (dir[i].name, name);
443 /* first read old sector data to cache */
444 lba28_drive_read (p, ZEXFS_IDIRENT_SECTOR+x, zexfs.cache);
446 /* in memory just rewrite dirent structure */
447 memcpy (zexfs.cache+(r-(x*512)), &dirent, sizeof (zexfs_dirent));
449 /* write new data from cache */
450 lba28_drive_write (p, ZEXFS_IDIRENT_SECTOR+x, zexfs.cache);
452 return 1;
455 /* go to next directory placed in current directory */
456 unsigned zexfs_cd (partition_t *p, unsigned char *name)
458 zexfs_dirent dirent;
460 int r = -1;
461 // kprintf ("name: %s : %d\n", name, strlen (name));
462 if (!strcmp (name, "..")) {
463 zexfs.node_curr = zexfs.node_prev;
465 r = zexfs_dirent_findbynode (p, &dirent, zexfs.node_prev);
466 // kprintf ("he: %d\n", r);
467 if (r == -1) {
468 kprintf ("ZeXFS -> dirent with this name not found\n");
469 return 0;
472 zexfs.node_prev = dirent.parent;
473 r = zexfs.node_prev;
474 // kprintf ("zexfs.node_prev: %d\n", zexfs.node_prev);
475 } else {
476 r = zexfs_dirent_find (p, &dirent, name);
477 // kprintf ("he2: %d\n", r);
478 if (r == -1) {
479 kprintf ("ZeXFS -> dirent with this name not found\n");
480 return 0;
483 zexfs.node_prev = zexfs.node_curr;
484 zexfs.node_curr = r;
487 // kprintf ("node_curr: %d\n", r);
488 // kprintf ("name: %s\n", dirent.name);
490 zexfs_dir_flush ();
492 unsigned y = 0;
493 unsigned x = -1;
494 unsigned id = 0;
495 unsigned i = 0;
497 if (zexfs.node_curr) {
498 strcpy (dir[0].name, "..");
499 id ++;
502 for (i = 0; i < zexfs.iblock.dirents + ZEXFS_DIRENT_PREALLOC; i ++) {
503 if (zexfs.dirents[i] != ZEXFS_DIRENT_FREE) {
504 unsigned s = i * sizeof (zexfs_dirent);
506 y = s/512;
508 /* read data from sector to cache */
509 if (x != y)
510 lba28_drive_read (p, ZEXFS_IDIRENT_SECTOR+y, zexfs.cache);
512 unsigned char *l = zexfs.cache + (s-(y*512));
513 zexfs_dirent *dirent = (zexfs_dirent *) l;
515 if (zexfs.node_curr == dirent->parent) {
516 // kprintf ("cd_root: %d : %s\n", (s-(y*512)), dirent->name);
518 memcpy (dir[id].name, dirent->name, 10);
519 dir[id].dir = dirent->flags & ZEXFS_DIRENT_DIR ? 1 : 0;
521 id ++;
524 x = y;
528 return 1;
531 /* go to root '/' directory on partition */
532 unsigned zexfs_cd_root (partition_t *p)
534 zexfs.node_curr = 0;
536 zexfs_dir_flush ();
538 unsigned i;
539 unsigned y = 0;
540 unsigned x = -1;
541 unsigned id = 0;
543 for (i = 0; i < zexfs.iblock.dirents + 32; i ++) {
544 if (zexfs.dirents[i] != ZEXFS_DIRENT_FREE) {
545 unsigned s = i * sizeof (zexfs_dirent);
547 y = s/512;
549 /* read data from sector to cache */
550 if (x != y)
551 lba28_drive_read (p, ZEXFS_IDIRENT_SECTOR+y, zexfs.cache);
553 unsigned char *l = zexfs.cache + (s-(y*512));
554 zexfs_dirent *dirent = (zexfs_dirent *) l;
556 if (zexfs.node_curr == dirent->parent) {
557 kprintf ("cd_root: %d : %s\n", (s-(y*512)), dirent->name);
559 memcpy (dir[id].name, dirent->name, 10);
560 dir[id].dir = dirent->flags & ZEXFS_DIRENT_DIR ? 1 : 0;
562 id ++;
565 x = y;
569 return 1;
572 /* mkzexfs utility for create zexfs filesystem on partition */
573 unsigned mkzexfs (partition_t *p)
575 if (!p)
576 return 0;
578 printf ("mkzexfs\n");
580 unsigned i;
581 for (i = 0; i < zexfs.iblock.dirents + ZEXFS_DIRENT_PREALLOC; i ++)
582 zexfs.dirents[i] = ZEXFS_DIRENT_FREE;
584 memcpy (zexfs.iblock.magic, "zexfs", 5);
586 zexfs.iblock.dirents = 0;
587 zexfs.iblock.blkents = 0;
589 memset (zexfs.cache, 0, 512);
590 memcpy (zexfs.cache, (void *) &zexfs.iblock, sizeof (zexfs_infoblock));
592 if (!lba28_drive_write (p, ZEXFS_INITBLOCK_SECTOR, zexfs.cache))
593 return 0;
595 memset (zexfs.cache, 0, 512);
597 for (i = ZEXFS_DIRENT_SECTOR; i < ZEXFS_IDIRENT_SECTOR; i ++) {
598 if (!lba28_drive_write (p, i, zexfs.cache))
599 return 0;
602 for (i = ZEXFS_IDIRENT_SECTOR; i < ZEXFS_IDIRENT_SECTOR+10; i ++) {
603 if (!lba28_drive_write (p, ZEXFS_IDIRENT_SECTOR, zexfs.cache))
604 return 0;
607 if (!lba28_drive_write (p, ZEXFS_BLKENT_SECTOR, zexfs.cache))
608 return 0;
610 zexfs.node_curr = 0;
611 zexfs.node_prev = 0;
613 /* create dirent with node id 0 - root directory */
614 zexfs_create_entity (p, ".", ZEXFS_DIRENT_FILE);
616 printf ("zexfs filesystem was succefully created\n");
618 return 1;
621 /* zexos filesystem initialization function */
622 unsigned zexfs_init (partition_t *p)
624 lba28_drive_read (p, ZEXFS_INITBLOCK_SECTOR, (unsigned char *) zexfs.cache);
626 memcpy (&zexfs.iblock, zexfs.cache, sizeof (zexfs.iblock));
628 if (strncmp (zexfs.iblock.magic, "zexfs", 5)) {
629 kprintf ("ZeXFS not found\n");
630 return 1;
633 kprintf ("ZeXFS -> filesystem contain %d dirents\n", zexfs.iblock.dirents);
634 kprintf ("ZeXFS -> filesystem contain %d blkents\n", zexfs.iblock.blkents);
636 /* alloc memory for dirents array */
637 zexfs.dirents = (unsigned char *) kmalloc ((zexfs.iblock.dirents+ZEXFS_DIRENT_PREALLOC) * sizeof (unsigned char));
639 if (!zexfs.dirents) {
640 kprintf ("ZeXFS -> zexfs.dirents : out of memory\n");
642 return 0;
645 /* alloc memory for blkents array */
646 zexfs.blkents = (unsigned char *) kmalloc ((zexfs.iblock.blkents+ZEXFS_BLKENT_PREALLOC) * sizeof (unsigned char));
648 if (!zexfs.blkents) {
649 kprintf ("ZeXFS -> zexfs.blkents : out of memory\n");
650 kfree (zexfs.dirents);
652 return 0;
655 /* clean end of memory block, where physical data are'nt loaded */
656 if (zexfs.iblock.dirents >= ZEXFS_DIRENT_PREALLOC)
657 memset (zexfs.dirents-ZEXFS_DIRENT_PREALLOC, 0, ZEXFS_DIRENT_PREALLOC);
658 else
659 memset (zexfs.dirents, 0, ZEXFS_DIRENT_PREALLOC);
661 /* clean end of memory block, where physical data are'nt loaded */
662 if (zexfs.iblock.blkents >= ZEXFS_BLKENT_PREALLOC)
663 memset (zexfs.blkents-ZEXFS_BLKENT_PREALLOC, 0, ZEXFS_BLKENT_PREALLOC);
664 else
665 memset (zexfs.blkents, 0, ZEXFS_BLKENT_PREALLOC);
667 unsigned i;
668 unsigned y = 0;
670 /* read dirent database from drive */
671 for (i = 0; i < zexfs.iblock.dirents; i += 512)
672 lba28_drive_read (p, ZEXFS_DIRENT_SECTOR+(i/512), (unsigned char *) ((unsigned char *) zexfs.dirents+((i/512)*512)));
674 /* read blkent database from drive */
675 for (i = 0; i < zexfs.iblock.blkents; i += 512)
676 lba28_drive_read (p, ZEXFS_BLKENT_SECTOR+(i/512), (unsigned char *) ((unsigned char *) zexfs.blkents+((i/512)*512)));
678 zexfs.node_curr = 0;
680 return 1;
683 /* handler which is used by device management and pretty needed
684 for communication between zexos and this filesystem */
685 bool zexfs_handler (unsigned act, char *block, unsigned n, unsigned long l)
687 switch (act) {
688 case FS_ACT_INIT:
690 return zexfs_init ((partition_t *) block);
692 break;
693 case FS_ACT_READ:
695 return zexfs_read_file (curr_part, dir[n].name, (vfs_content_t *) block);
697 break;
698 case FS_ACT_WRITE:
700 return zexfs_write_file (curr_part, dir[n].name, (vfs_content_t *) block);
702 break;
703 case FS_ACT_CHDIR:
705 if (n == -1)
706 return zexfs_cd_root (curr_part);
708 /* go to another directory */
709 return zexfs_cd (curr_part, block);
711 break;
712 case FS_ACT_MKDIR:
714 return zexfs_create_entity (curr_part, block, ZEXFS_DIRENT_DIR);
716 break;
717 case FS_ACT_TOUCH:
719 return zexfs_create_entity (curr_part, block, ZEXFS_DIRENT_FILE);
723 return 0;
725 #endif