Subversion Repositories shark

Rev

Rev 33 | Go to most recent revision | 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) 2000 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
/*
33 pj 37
 * CVS :        $Id: fs.h,v 1.2 2002-11-11 08:40:44 pj Exp $
2 pj 38
 *
39
 * File:        $File$
33 pj 40
 * Revision:    $Revision: 1.2 $
41
 * Last update: $Date: 2002-11-11 08:40:44 $
2 pj 42
 */
43
 
44
/***
45
 This file contains the registration functions for filesystems mudules and the blocking functions
46
 used internally for filesystem primitive calls.
47
 ***/
48
 
49
#ifndef __FS_H__
50
#define __FS_H__
51
 
52
#include <fs/types.h>
53
#include <fs/mount.h>
33 pj 54
#include <time.h>
2 pj 55
 
56
#include "mutex.h"
57
#include "semaph.h"
58
 
59
struct super_block;
60
 
61
/*+
62
 This structure is used to inform the file system manager that a new
63
 filesystem is ready to bind data on some device:
64
 
65
 name
66
   It's the name of the filesystem; can be any string.
67
 fs_flags
68
   I don't remember what it is
69
 fs_ind
70
   It's a unique identifier for the filesystem; it is taken from the
71
   PC IBM hard disk architecture
72
 read_super
73
   It's the main entry point to the fileystem: the mount function call
74
   this routine to perform the initial binding between a disk device and
75
   a filesystem; the struct super_block it is the only thing that
76
   the filesystem manager required to perform a disk operation.
77
 
78
 +*/
79
struct file_system_type {
80
  /*+ filesystem name +*/
81
  const char *name;
82
  /*+ filesystem flags +*/
83
  int        fs_flags;
84
  /*+ filesystem indicator +*/
85
  __uint8_t  fs_ind;
86
 
87
  /*+ filesystem read_super function +*/
88
  struct super_block *(*read_super)(__dev_t device, __uint8_t fs_ind,
89
                                    struct mount_opts *options);
90
};
91
 
92
 
93
int filesystem_register(struct file_system_type *ptr);
94
struct file_system_type *filesystem_find_byid(__uint8_t fs_ind);
95
 
96
int mount_device(__dev_t device, __uint8_t fs_ind, char *pathname,
97
                 struct mount_opts *opts);
98
 
99
int umount_device(__dev_t device);
100
 
101
/*
102
 *
103
 *
104
 *
105
 */
106
 
107
/* define this if you want to debug the synchronization functions */
108
#define FS_DEBUGSYNC KERN_DEBUG
109
#undef FS_DEBUGSYNC
110
 
111
#ifdef FS_DEBUGSYNC
112
#define _printk0(fmt,args...) cprintf(fmt,##args)
113
#else
114
#define _printk0(fmt,args...)
115
#endif
116
 
117
/*+ state of the fs: 0 can accept syscalls - 1 abort all syscalls +*/
118
extern int              fssysstate;
119
/*+ number of syscalls in progress +*/
120
extern long             fssyscounter;
121
/*+ mutex to update the above two variables +*/
122
extern __fs_fastmutex_t fssysmutex;
123
/*+ syncronization semaphore to change fssysstate +*/
124
extern __fs_sem_t       fssyssync;
125
/*+ number of task waiting for fs +*/
126
extern long             fssysinitcounter;
127
/*+ syncronization semaphore to change fssysstate from -1 to 0 +*/
128
extern __fs_sem_t       fssysinit;
129
 
130
/*+ prolog for all syscalls +*/
131
static __inline__ int __call_to_fs(void)
132
{
133
  __fs_fastmutex_lock(&fssysmutex);
134
  if (fssysstate!=0) {
135
    __fs_fastmutex_unlock(&fssysmutex);
136
    return -1;
137
  }
138
  fssyscounter++;
139
  __fs_fastmutex_unlock(&fssysmutex);
140
  return 0;
141
}
142
 
143
#define call_to_fs() { if (__call_to_fs()) return -ENOENT; }
144
 
145
/*+ release temporally a syscall (very dangerous) +*/
146
static __inline__ void release_sys_call(void)
147
{
148
  __fs_fastmutex_lock(&fssysmutex);
149
  fssyscounter--;
150
  __fs_fastmutex_unlock(&fssysmutex);
151
}
152
 
153
/*+ reaquire a syscall (MUST be tested the return value for abort) +*/
154
static __inline__ int reacquire_sys_call(void)
155
{
156
  int ret=0;
157
  __fs_fastmutex_lock(&fssysmutex);
158
  if (fssysstate==1) ret=-1;
159
  else fssyscounter++;
160
  __fs_fastmutex_unlock(&fssysmutex);
161
  return ret;
162
}
163
 
164
/*+ epilog for all syscalls +*/
165
static __inline__ int __return_from_fs(int code)
166
{
167
  __fs_fastmutex_lock(&fssysmutex);
168
  fssyscounter--;
169
  if (fssysstate==1) {
170
    if (fssyscounter==0) {
171
      __fs_fastmutex_unlock(&fssysmutex);
172
      __fs_sem_signal(&fssyssync);
173
      return (code);
174
    }
175
  }
176
  __fs_fastmutex_unlock(&fssysmutex);
177
  return (code);
178
}
179
 
180
#define return_from_fs(code) return __return_from_fs(code)
181
 
182
#define fs_test_cancellation(code) \
183
{  \
184
  if (proc_table[exec_shadow].control & KILL_ENABLED && \
185
      proc_table[exec_shadow].control & KILL_REQUEST ) { \
186
    __return_from_fs(0); \
187
    task_testcancel(); \
188
    return (code); \
189
  } \
190
}
191
 
192
/*+ called only one time when the system is ready +*/
193
static __inline__ void permit_all_fs_calls(void)
194
{
195
  _printk0("<pfscall>");
196
  __fs_fastmutex_lock(&fssysmutex);
197
  fssysstate=0;
198
  if (fssysinitcounter>0) {
199
    __fs_fastmutex_unlock(&fssysmutex);
200
    _printk0("<pfscall:%li>",fssysinitcounter);
201
    while (fssysinitcounter-->0)
202
      __fs_sem_signal(&fssysinit);
203
    return;
204
  }
205
  __fs_fastmutex_unlock(&fssysmutex);
206
}
207
 
208
#define SHUTDOWNTIMEOUT 6000000
209
#define SHUTDOWNSLICE    250000
210
#define SHUTDOWNCOUNTER (SHUTDOWNTIMEOUT/SHUTDOWNSLICE)
211
 
212
/*+ called only one during shutdown to disable syscalls +*/
213
static __inline__ void block_all_fs_calls(void)    
214
{
215
  _printk0("<bfscall>");
216
  __fs_fastmutex_lock(&fssysmutex);
217
  fssysstate=1;
218
  if (fssyscounter>0) {
219
    _printk0("<bfscallfor%li>",fssyscounter);
220
    __fs_fastmutex_unlock(&fssysmutex);
221
    _printk0("<bfscallwait>");
222
 
223
#ifdef SHUTDOWNTIMEOUT
224
    {
225
      int counter;
33 pj 226
      struct timespec delay;
227
      delay.tv_sec=SHUTDOWNSLICE/1000000;
228
      delay.tv_nsec=(SHUTDOWNSLICE%1000000)*1000;
2 pj 229
      counter=0;
230
      while (counter<SHUTDOWNCOUNTER&&__fs_sem_trywait(&fssyssync)) {
231
        counter++;
33 pj 232
        nanosleep(&delay, NULL);
2 pj 233
      }
234
      if (counter>=SHUTDOWNCOUNTER) {
235
        printk(KERN_NOTICE "filesystem shutdown timeout... aborting!");
236
        sys_abort(371);
237
      }
238
    }
239
#else
240
    __fs_sem_wait(&fssyssync);
241
#endif
242
 
243
    _printk0("<bfscallresum>");
244
  } else {
245
    __fs_fastmutex_unlock(&fssysmutex);
246
  }
247
}
248
 
249
 
250
#endif