Subversion Repositories shark

Rev

Rev 38 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 1
/*
2
 * Project: HARTIK (HA-rd R-eal TI-me K-ernel)
3
 *
4
 * Coordinators: Giorgio Buttazzo <giorgio@sssup.it>
5
 *               Gerardo Lamastra <gerardo@sssup.it>
6
 *
7
 * Authors     : Massimiliano Giorgi <massy@hartik.sssup.it>
8
 * (see authors.txt for full list of hartik's authors)
9
 *
10
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
11
 *
12
 * http://www.sssup.it
13
 * http://retis.sssup.it
14
 * http://hartik.sssup.it
15
 */
16
 
17
/*
18
 * Copyright (C) 1999 Massimiliano Giorgi
19
 *
20
 * This program is free software; you can redistribute it and/or modify
21
 * it under the terms of the GNU General Public License as published by
22
 * the Free Software Foundation; either version 2 of the License, or
23
 * (at your option) any later version.
24
 *
25
 * This program is distributed in the hope that it will be useful,
26
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28
 * GNU General Public License for more details.
29
 *
30
 * You should have received a copy of the GNU General Public License
31
 * along with this program; if not, write to the Free Software
32
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
33
 *
34
 */
35
 
36
/*
38 pj 37
 * CVS :        $Id: fs.c,v 1.2 2003-01-07 17:14:05 pj Exp $
2 pj 38
 *
39
 * File:        $File$
38 pj 40
 * Revision:    $Revision: 1.2 $
41
 * Last update: $Date: 2003-01-07 17:14:05 $
2 pj 42
 */
43
 
44
#include "dentry.h"
45
 
46
#include <kernel/func.h>
47
 
48
#include <fs/util.h>
49
#include <fs/types.h>
50
#include <fs/const.h>
51
#include <fs/bdev.h>
52
#include <fs/fsconf.h>
53
#include <fs/fsinit.h>
54
#include <fs/major.h>
55
#include <fs/fs.h>
56
#include <fs/sysmacro.h>
57
#include <fs/fsind.h>
58
#include <fs/assert.h>
59
#include <fs/mount.h>
60
#include <fs/errno.h>
61
#include <fs/task.h>
62
 
63
#include "mutex.h"
64
#include "fs.h"
65
#include "dcache.h"
66
#include "inode.h"
67
#include "super.h"
68
#include "superop.h"
69
#include "file.h"
70
#include "fileop.h"
71
#include "fsconst.h"
72
 
73
#include "debug.h"
74
 
75
// number of filesystem types supported
76
#define MAXFILESYSTEMS 8
77
 
78
// pointer into "fst"
79
static int nextfs=0;
80
// file system that are registered 
81
static struct file_system_type *fst[MAXFILESYSTEMS];
82
 
83
NOP_mutexattr_t fsdef_mutexattr=NOP_MUTEXATTR_INITIALIZER;
84
//static __fs_mutex_t    mutex;
85
void            *fsmutexattr=NULL;
86
 
87
/* if an assert fails into this module this go UP */
88
int fs_crash=0;
89
 
90
 
91
/*
92
 * used to block all filesystem calls
93
 */
94
 
95
/*+ state of the fs +*/
96
/*+ -1: before initialization 0:system calls allowed 1:calls rejected +*/
97
int              fssysstate=-1;
98
/*+ number of syscalls in progress +*/
99
long             fssyscounter=0;
100
/*+ mutex to update the above two variables +*/
101
__fs_fastmutex_t fssysmutex;
102
/*+ syncronization semaphore to change fssysstate from 0 to 1 +*/
103
__fs_sem_t       fssyssync;
104
/*+ number of task waiting for fs +*/
105
long             fssysinitcounter=0;
106
/*+ syncronization semaphore to change fssysstate from -1 to 0 +*/
107
__fs_sem_t       fssysinit;
108
 
109
/*
110
 * variables needed to have a proper filesystem shutdown
111
 */
112
 
113
/*+ number of module that needs filesystem support +*/
114
long             needcounter=0;
115
/*+ syncronization semaphore to start a filesystem shutdown +*/
116
__fs_sem_t       needsync;
117
 
118
/**
119
   This is the first function that must be called prior to call
120
   another function if the filesystem module; it initialize every
121
   sub-module of the filesystem.
122
   @memo
123
   @param ptr
124
   a pointer to a structure that contains information on how initialize
125
   the filesystem
126
   @return
127
 
128
*/
129
 
130
void filesystem_end(void *);
131
 
132
int filesystem_init(FILESYSTEM_PARMS *ptr)
133
{
134
  int result;
135
  int i,fd;
136
 
137
  printk(KERN_INFO "initializing filesystems...");
138
  printkb("fs_init: START");
139
 
140
  //__fs_mutex_init(&mutex);
141
 
142
  __fs_fastmutex_init(&fssysmutex);
143
  __fs_sem_init(&fssyssync,0);
144
  __fs_sem_init(&needsync,0);
145
  __fs_sem_init(&fssysinit,0);
146
 
147
 
148
  fsmutexattr=ptr->fs_mutexattr;
149
  if (fsmutexattr==NULL) {
150
    printk(KERN_ERR "filesystem_init failed: mutex attribute not specified!");
151
    printkb("fs_init: END");
152
    return -1;
153
  }
154
 
155
  nextfs=0;
156
  for (i=0;i<MAXFILESYSTEMS;i++)
157
    fst[i]=NULL;
158
 
159
  printkb("fs_init: initiating cache...");
160
  dcache_init();
161
 
162
  printkb("fs_init: initiating supers...");
163
  super_init();
164
  printkb("fs_init: initiating inodes...");
165
  inode_init();
166
  printkb("fs_init: initiating dentries...");
167
  dentry_init();
168
 
169
  /*--*/
170
 
171
#ifdef MSDOS_FILESYSTEM
172
  printkb("fs_init: initiating FAT16 filesystem...");
173
  msdos_fs_init(ptr);
174
#endif
175
 
176
  /*--*/
177
 
178
  printkb("fs_init: mounting root...");
179
  result=mount_root(ptr->device,ptr->fs_ind,ptr->fs_opts);
180
  if (result!=0) {
181
    /*if (ptr->fs_showinfo)*/
182
    printk(KERN_CRIT "Mounting root FAILED! (error: %i)",result);
183
    /* for safety */
184
    _assert(result==0);
185
    printkb("fs_init: END");
186
    return result;
187
  }
188
 
189
  /*--*/
190
 
191
  /* must be done after mounting of the root filesystem because
192
   * the file descriptors table of every process contains a
193
   * pointer to a 'struct dentry' (the current working directory)
194
   */
195
 
196
  printkb("fs_init: initiating files...");
197
  file_init();
198
 
199
  /*--*/
200
 
201
  /* to do better: reserve the first 3 file descriptors for
202
   * console I/O  
203
   */
204
 
205
  printkb("fs_init: initiating console descriptors...");
206
  for (i=0;i<3;i++) {
207
    fd=get_fd(__get_pid(),(void*)-1);
208
    if (fd!=i) {
209
      printk(KERN_CRIT "Can't reserve file descriptor %i for console i/o",fd);
210
      _assert(fd==i);
211
      return -1;
212
    }
213
  }
214
 
215
  /*--*/
216
 
217
  printkb("fs_init: initiating shutdown routines...");
218
  sys_atrunlevel(filesystem_end,NULL,RUNLEVEL_SHUTDOWN);  
219
 
220
  /* -- */
221
 
222
  permit_all_fs_calls();
223
 
224
  printkb("fs_init: END");
225
  return 0;
226
}
227
 
228
/*+
229
   This function is used to find what filesystem module manage the
230
   requested file system indicator
231
   @memo
232
   @param fs_ind
233
   the file system to find
234
   @return
235
   the file system struct or NULL in case of error
236
+*/
237
struct file_system_type *filesystem_find_byid(BYTE fs_ind)
238
{
239
  int i;
240
  for (i=0;i<nextfs;i++)
241
    if (fst[i]->fs_ind==fs_ind) return fst[i];
242
  return NULL;
243
}
244
 
245
/*+
246
   This function is used by a filesystem to register itself to the
247
   filesystem manager; can be called more than one time.
248
   @memo
249
   @param ptr
250
   a pointer to the strutc file\_system\_type of that filesystem
251
   @return
252
 
253
   @see file\_system\_type
254
   +*/
255
 
256
int filesystem_register(struct file_system_type *ptr)
257
{
258
  if (nextfs==MAXFILESYSTEMS) return -1;
259
  fst[nextfs]=ptr;
260
  nextfs++;
261
  return 0;
262
}
263
 
264
__uint8_t filesystem_find_byname(char *name)
265
{
266
  int i;
267
  for (i=0;i<nextfs;i++)
268
    if (!strcmp(name,(char *)fst[i]->name)) return fst[i]->fs_ind;
269
  return 255;  
270
}
271
 
272
/* --- */
273
 
274
int mount_root(__dev_t device, __uint8_t fs_ind,
275
               struct mount_opts *opts)
276
{
277
  struct super_block      *sb;
278
  struct file_system_type *ptr;
279
  int res;
280
 
281
  printk9("START mount_root()");
282
 
283
  ptr=filesystem_find_byid(fs_ind);
284
  if (ptr==NULL) {
285
    printk(KERN_CRIT "mount_root(): errore -2");
286
    return -2;
287
  }
288
 
289
  printk9("mount_root(): filesystem type '%s'",ptr->name);
290
  printk9("mount_root(): filesystem entry at %p",(void *)ptr->read_super);
291
  printk9("mount_root(): filesystem found");
292
 
293
  res=dcache_lockdevice(device);
294
  _assert(res!=DCACHE_ERR);
295
  if (res==DCACHE_FAIL) {
296
    printk(KERN_CRIT "mount_root(): errore -6");
297
    return -6;
298
  }
299
 
300
  printk9("mount_root(): device locked");
301
 
302
  sb=ptr->read_super(device,fs_ind,opts);
303
  if (sb==NULL) {
304
    printk(KERN_CRIT "mount_root(): errore -4");
305
    return -4;
306
  }
307
  sb->sb_dev=device;
308
  sb->sb_fs=ptr;
309
  sb->sb_parent=NULL;
310
  sb->sb_childs=NULL;
311
  sb->sb_next=NULL;
312
 
313
  printk9("mount_root(): super read");
314
 
315
  set_root_superblock(sb);
316
 
317
  res=set_root_dentry(sb);
318
  if (res) {
319
    printk(KERN_CRIT "mount_root(): errore -5");
320
    return -5;
321
  }
322
 
323
  printk9("mount_root(): root dentry set");
324
 
325
  /* so other task can use this superblock */
326
  super_release(sb);
327
 
328
  printk9("mount_root(): super available");
329
 
330
  {
331
    char *n0,*n1;
332
    bdev_findname(device,&n0,&n1);
333
    printk(KERN_INFO "mounted %s%c%s (%s) on /",
334
           n0,DIRDELIMCHAR,n1,
335
           opts->flags&MOUNT_FLAG_RW?"rw":"ro");
336
  }
337
 
338
  printk9("END mount_root()");
339
 
340
  return 0;
341
}
342
 
343
/* --- */
344
 
345
int mount_device(__dev_t device, __uint8_t fs_ind, char *pathname,
346
                 struct mount_opts *opts)
347
{
348
  struct file_system_type *fs;
349
  struct super_block      *sb,*psb;
350
  struct dentry           *de;
351
  int ret,res;
352
 
353
  printk9("START mount_device()");
354
 
355
  fs=filesystem_find_byid(fs_ind);
356
  if (fs==NULL) {
357
    printk(KERN_ERR
358
           "mount_device(): can't find filesystem");
359
    return -ENODEV;
360
  }
361
 
362
  de=find_dentry_from(NULL,pathname);
363
  if (de==NULL) {
364
    printk(KERN_ERR
365
           "mount_device(): can't find directory entry");
366
    return -ENOENT;
367
  }
368
 
369
  if (!__S_ISDIR(de->d_inode->i_st.st_mode)) {
370
    printk(KERN_ERR
371
           "mount_device(): pathname is not a directory");
372
    unlock_dentry(de);
373
    return -ENOTDIR;
374
  }
375
 
376
  res=dcache_lockdevice(device);
377
  _assert(res!=DCACHE_ERR);
378
  if (res==DCACHE_FAIL) {
379
    unlock_dentry(de);
380
    printk(KERN_ERR "mount_device(): can't lock device");
381
    return -EBUSY;
382
  }
383
 
384
  sb=fs->read_super(device,fs_ind,opts);
385
  if (sb==NULL) {
386
    unlock_dentry(de);
387
    printk(KERN_ERR
388
           "mount_device(): can't read superblock");
389
    return -EINVAL;
390
  }
391
  sb->sb_dev=device;
392
  sb->sb_fs=fs;
393
  psb=de->d_sb;
394
 
395
  ret=mount_dentry(sb,de);
396
  if (ret) {
397
    unlock_dentry(de);
398
    super_freeblock(sb);
399
    printk(KERN_ERR
400
           "mount_device(): can't associate directory entry with superblock");
401
    return -EBUSY;    
402
  }
403
 
404
  /* insert superblock into tree */
405
  super_insertintotree(sb,psb);
406
 
407
  /* so other task can use this superblock */
408
  super_release(sb);
409
 
410
  {
411
    char *n0,*n1;
412
    bdev_findname(device,&n0,&n1);
413
    printk(KERN_INFO "mounted %s%c%s (%s) on %s",
414
           n0,DIRDELIMCHAR,n1,
415
           opts->flags&MOUNT_FLAG_RW?"rw":"ro",
416
           pathname);
417
  }
418
 
419
  printk9("END mount_device()");
420
  return 0;
421
}
422
 
423
/*
424
int mount_device(__dev_t device, __uint8_t fs_ind, char *pathname,
425
                 struct mount_opts *opts)
426
{
427
  int res;
428
  //__fs_mutex_lock(&mutex);
429
  res=__mount_device(device,fs_ind,pathname,opts);
430
  //__fs_mutex_unlock(&mutex);
431
  return res;
432
}
433
*/
434
 
435
int umount_device(__dev_t device)
436
{
437
  char path[1024];
438
  struct super_block *sb;
439
  int res;
440
  char *n0,*n1;
441
 
442
  printk9("START umount_device()");
443
 
444
  if (device==get_root_device()) {
445
    printk9(KERN_ERR
446
           "umount_device(): can't umount root");
447
    return -EBUSY;
448
  }
449
 
450
  sb=super_aquire(device);
451
  if (sb==NULL) {
452
    printk9(KERN_ERR
453
           "umount_device(): can't aquire super block");
454
    printk(KERN_ERR "can't unmount device 0x%04x",device);
455
    return -EBUSY;
456
  }
457
 
458
  printk9("getting pathname");
459
 
460
  /* get names for logging */
461
  getfullname_dentry(sb->sb_droot,path,sizeof(path));
462
  bdev_findname(device,&n0,&n1);
463
 
464
  printk9("checking for childs super_blocks");
465
 
466
  if (sb->sb_childs!=NULL) {
467
    super_release(sb);
468
    printk9(KERN_ERR
469
           "umount_device(): super block has childs");
470
    printk(KERN_ERR "can't unmount %s%c%s from %s",n0,DIRDELIMCHAR,n1,path);
471
    return -EBUSY;    
472
  }
473
 
474
  printk9("calling virtual function put_super");
475
 
476
  res=sb->sb_op->put_super(sb);
477
  if (res!=0) {
478
    super_release(sb);
479
    printk9(KERN_ERR
480
           "umount_device(): can't put_super");
481
    printk(KERN_ERR "can't unmount %s%c%s from %s",n0,DIRDELIMCHAR,n1,path);
482
    return -EIO;
483
  }
484
 
485
  printk9("calling umount_dentry");
486
 
487
  res=umount_dentry(sb);
488
  if (res!=0) {
489
    super_release(sb);
490
    printk9(KERN_ERR
491
           "umount_device(): can't umount directory tree");
492
    printk(KERN_ERR "can't unmount %s%c%s from %s",n0,DIRDELIMCHAR,n1,path);
493
    return -EBUSY;
494
  }
495
 
496
  /* this is not needed but allows sync of cache with hard-diskes */
497
  res=dcache_purgedevice(device,0);
498
  /*
499
    the dentry has been unmounted so we must continue
500
  if (res!=0) {
501
    super_release(sb);
502
    printk(KERN_ERR
503
           "umount_device(): can't sync cache with hard-disk");
504
    return -EIO;
505
  }
506
  */
507
 
508
  res=dcache_unlockdevice(device);
509
  _assert(res!=DCACHE_ERR);
510
  if (res!=DCACHE_OK) {
511
    // we must not go here
512
    _assert(0==-1);
513
    super_release(sb);
514
    printk9(KERN_ERR
515
           "umount_device(): can't unlock device.cache");
516
    printk(KERN_ERR "can't unmount %s%c%s from %s",n0,DIRDELIMCHAR,n1,path);
517
    return -EBUSY;
518
  }
519
 
520
  /* remove superblock from tree */
521
  super_removefromtree(sb);
522
 
523
  /* free superblock! */
524
  super_freeblock(sb);
525
 
526
  printk(KERN_INFO "unmounted %s%c%s from %s",n0,DIRDELIMCHAR,n1,path);
527
 
528
  printk9("END umount_device()");
529
  return EOK;
530
}
531
 
532
/*
533
int umount_device(__dev_t device)
534
{
535
  int res;
536
  //__fs_mutex_lock(&mutex);
537
  res=__umount_device(device);
538
  //__fs_mutex_unlock(&mutex);
539
  return res;
540
}
541
*/
542
 
543
int umount_root(void)
544
{
545
  struct super_block *sb;
546
  __dev_t device;
547
  int res;
548
  char *n0,*n1;
549
 
550
  printk9("START umount_root()");
551
  device=get_root_device();
552
 
553
  sb=super_aquire(device);
554
  if (sb==NULL) {
555
    printk9(KERN_ERR
556
           "umount_root(): can't aquire super block");
557
    printk(KERN_ERR "can't unmount device 0x%04x",device);
558
    return -EBUSY;
559
  }
560
 
561
  /* get names for logging */
562
  bdev_findname(device,&n0,&n1);
563
 
564
  printk9("unsetting root");
565
 
566
  set_root_superblock(NULL);  
567
  set_root_dentry(NULL);
568
 
569
  printk9("calling umount_dentry");
570
 
571
  res=umount_dentry(sb);
572
  printk9("called umount_dentry");
573
  if (res!=0) {
574
    super_release(sb);
575
    printk9(KERN_ERR
576
           "umount_root(): can't umount directory tree");
577
    printk(KERN_ERR "can't unmount %s%c%s from /",n0,DIRDELIMCHAR,n1);
578
    return -EBUSY;
579
  }
580
 
581
  printk9("calling virtual function put_super");
582
 
583
  /* */
584
  res=sb->sb_op->put_super(sb);
585
  if (res!=0) {
586
    super_release(sb);
587
    printk9(KERN_ERR
588
           "umount_root(): can't put_super");
589
    printk(KERN_ERR "can't unmount %s%c%s from /",n0,DIRDELIMCHAR,n1);
590
    return -EIO;
591
  }
592
 
593
  /* this is not needed but allows sync of cache with hard-diskes */
594
  res=dcache_purgedevice(device,0);
595
  if (res!=0) {
596
    super_release(sb);
597
    printk9(KERN_ERR
598
           "umount_root(): can't sync cache with hard-disk");
599
    printk(KERN_ERR "can't unmount %s%c%s from /",n0,DIRDELIMCHAR,n1);
600
    return -EIO;
601
  }
602
 
603
  res=dcache_unlockdevice(device);
604
  _assert(res!=DCACHE_ERR);
605
  if (res!=DCACHE_OK) {
606
    super_release(sb);
607
    printk9(KERN_ERR
608
           "umount_root(): can't unlock device.cache");
609
    printk(KERN_ERR "can't unmount %s%c%s from /",n0,DIRDELIMCHAR,n1);
610
    return -EBUSY;
611
  }
612
 
613
  /* free superblock! */
614
  super_freeblock(sb);
615
 
616
  printk(KERN_INFO "unmounted %s%c%s from /",n0,DIRDELIMCHAR,n1);
617
 
618
  printk9("END umount_root()");
619
  return EOK;
620
}
621
 
622
/* -- */
623
 
624
int suspend_fs_shutdown(void)
625
{
626
  SYS_FLAGS f;
627
  _printk0("<ssd%i>",exec_shadow);
628
  f=kern_fsave();
629
  if (needcounter==-1) {
630
    kern_frestore(f);
631
    _printk0("<ssd%ifail>",exec_shadow);
632
    return -1;
633
  }
634
  needcounter++;
635
  kern_frestore(f);
636
  _printk0("<ssd%i,%li>",exec_shadow,needcounter);
637
  return 0;
638
}
639
 
640
void resume_fs_shutdown(void)
641
{
642
  SYS_FLAGS f;
643
  _printk0("<rfs%i>",exec_shadow);
644
  f=kern_fsave();
645
  needcounter--;
646
  if (needcounter==0) {
647
    needcounter=-1;
648
    kern_frestore(f);      
649
    _printk0("<rfs%isig>",exec_shadow);
650
    __fs_sem_signal(&needsync);
651
    return;
652
  }
653
  kern_frestore(f);
654
}
655
 
656
/*+ wait the initialization of the fs +*/
657
int wait_for_fs_initialization(void)
658
{
659
  int ret=0;
660
  _printk0("<wfi%i>",exec_shadow);
661
  __fs_fastmutex_lock(&fssysmutex);
662
  if (fssysstate==-1) {
663
    fssysinitcounter++;
664
    __fs_fastmutex_unlock(&fssysmutex);
665
    _printk0("<wfi%ib>",exec_shadow);
666
    __fs_sem_wait(&fssysinit);
667
    _printk0("<wfi%ir>",exec_shadow);
668
    return 0;
669
  } else if (fssysstate==1) ret=-1;
670
  __fs_fastmutex_unlock(&fssysmutex);
671
  _printk0("<wfi%i,%i>",exec_shadow,ret);
672
  return ret;
673
}
674
 
675
void wait_for_notneed(void)
676
{
677
  SYS_FLAGS f;
678
  f=kern_fsave();
679
  printkc("fs_shut: needcounter=%li",needcounter);
680
  if (needcounter>0) {
681
    printkc("fs_shut%i: synch needed (sem=%i)",exec_shadow,
682
            internal_sem_getvalue(&needsync));
683
    kern_frestore(f);
684
    __fs_sem_wait(&needsync);
685
    printkc("fs_shut%i: synch OK",exec_shadow);
686
    return ;
687
  }
688
  needcounter=-1;
689
  kern_frestore(f);
690
}
691
 
692
/* -- */
693
 
694
static int filecount=0;
695
 
696
static void func2(struct file *f)
697
{
698
  filecount++;
699
  f->f_op->close(f->f_dentry->d_inode,f);
700
  unlock_dentry(f->f_dentry);
701
  /* so operations on this file fail */
702
  f->f_count=0;
703
  return;
704
}
705
 
706
static int func(__dev_t device)
707
{
708
  int res;
709
  if (device==get_root_device()) return 0;
710
  res=umount_device(device);
711
  if (res) return -1;
712
  return 0;
713
}
714
 
715
TASK filesystem_shutdown(void *dummy)
716
{
717
  int res;
718
 
719
  printkc("fs_shut%i: START",exec_shadow);
720
 
721
  /*
722
  for (res=0;res<4*3;res++) {
723
    cprintf("Û");
724
    task_delay(250000l);
725
  }
726
  printk(KERN_DEBUG "TASK %i",exec_shadow);
727
  */
728
 
729
  /* wait for modules */
730
  printkc("fs_shut%i: waiting for modules that use filesystems",exec_shadow);  
731
  wait_for_notneed();
732
 
733
  /* block all filesystem calls */
734
  printkc("fs_shut%i: blocking all filesystem system calls",exec_shadow);
735
  printkc("fs_shut: task into filesystems primitives are %li",fssyscounter);
736
  block_all_fs_calls();
737
 
738
  /* close all files */
739
  printkc("fs_shut%i: closing all files",exec_shadow);
740
  enums_file(func2);
741
  printkc("fs_shut%i: closed %i files",exec_shadow,filecount);
742
 
743
  /* umount all devices */
744
  printkc("fs_shut: umounting all devices");
745
  res=super_enumdevice(func);
746
  if (res!=0) {
747
    printk(KERN_INFO "filesystems shutdown aborted!");
748
    printkc("fs_shut: ABORTING");
749
    return (void*)-1;
750
  }
751
 
752
  /* umount root device */
753
  printkc("fs_shut: umount root");
754
  res=umount_root();
755
  if (res!=0) {
756
    char *n0,*n1;
757
    bdev_findname(get_root_device(),&n0,&n1);
758
    printk(KERN_ERR "can't unmount %s%c%s from /",n0,DIRDELIMCHAR,n1);
759
    printk(KERN_INFO "filesystems shutdown aborted!");
760
    printkc("fs_shut: ABORTING");
761
    return (void*)-1;
762
  }
763
 
764
  printkc("fs_shut: END");
765
 
766
  return (void*)0;
767
}
768
 
769
void filesystem_end(void *dummy)
770
{
771
  SOFT_TASK_MODEL model;
772
  PID pid;
773
 
774
  printkc("fs_end: START");
775
 
776
  if (fs_crash) {
777
    printkc("fs_end: END");
778
    return;
779
  }
780
  printk(KERN_INFO "shuting down filesystems...");
781
 
782
  //nrt_task_default_model(model);
783
  //nrt_task_def_system(model);
784
 
785
  soft_task_default_model(model);
786
  soft_task_def_system(model);
787
  soft_task_def_notrace(model);
788
  soft_task_def_periodic(model);
789
  soft_task_def_period(model,50000);
790
  soft_task_def_met(model,10000);
791
  soft_task_def_wcet(model,10000);
792
 
793
  pid=task_create("ShutFS",filesystem_shutdown,&model,NULL);
794
  if (pid==-1)
795
    printk(KERN_ERR "can't start filesystem shutdown task");
796
  else {
797
    printkc("fs_end: shutting down task %i activated",pid);
798
    task_activate(pid);
799
  }
800
 
801
  printkc("fs_end: END");
802
}