Subversion Repositories shark

Rev

Details | 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
/*
37
 * CVS :        $Id: super.c,v 1.1.1.1 2002-03-29 14:12:50 pj Exp $
38
 *
39
 * File:        $File$
40
 * Revision:    $Revision: 1.1.1.1 $
41
 * Last update: $Date: 2002-03-29 14:12:50 $
42
 */
43
 
44
#include <fs/sysmacro.h>
45
#include <fs/util.h>
46
#include <fs/major.h>
47
#include <fs/fsinit.h>
48
#include <fs/bdev.h>
49
#include <fs/fsind.h>
50
#include <fs/mount.h>
51
#include <fs/assert.h>
52
 
53
#include "mutex.h"
54
#include "fs.h"
55
#include "super.h"
56
 
57
#define MAXSUPERBLOCKS 8
58
static __fs_mutex_t mutex;
59
static __fs_mutex_t mutexsb;
60
static struct super_block sbs[MAXSUPERBLOCKS];
61
 
62
static struct super_block *root_superblock=NULL;
63
 
64
int super_init(void)
65
{
66
  int i;
67
 
68
  __fs_mutex_init(&mutex);
69
  __fs_mutex_init(&mutexsb);
70
 
71
  for (i=0;i<MAXSUPERBLOCKS;i++) {
72
    memset(sbs+i,0,sizeof(struct super_block));
73
    mount_std_parms(sbs[i].sb_mopts);
74
    sbs[i].sb_busycount=0;
75
    sbs[i].sb_used=0;
76
    sbs[i].sb_blocked=0;
77
  }
78
 
79
  return 0;
80
}
81
 
82
struct super_block *super_getblock(void)
83
{
84
  struct super_block *ptr=NULL;
85
  int i;
86
 
87
  __fs_mutex_lock(&mutexsb);
88
  for (i=0;i<MAXSUPERBLOCKS;i++)
89
    if (!sbs[i].sb_used) {
90
      sbs[i].sb_used=1;
91
      sbs[i].sb_blocked=1;
92
      sbs[i].sb_busycount=0;
93
      ptr=sbs+i;
94
      break;
95
    }
96
  __fs_mutex_unlock(&mutexsb);
97
 
98
  return ptr;
99
}
100
 
101
void super_freeblock(struct super_block *ptr)
102
{
103
  __fs_mutex_lock(&mutexsb);
104
  _assert(ptr->sb_used==1);
105
  _assert(ptr->sb_blocked==1);
106
  _assert(ptr->sb_busycount==0);
107
  ptr->sb_used=0;
108
  __fs_mutex_unlock(&mutexsb);
109
}
110
 
111
/* --- */
112
 
113
struct super_block *get_root_superblock(void)
114
{
115
  _assert(root_superblock!=NULL);
116
  return root_superblock;
117
}
118
 
119
void set_root_superblock(struct super_block *sb)
120
{
121
  __fs_mutex_lock(&mutex);
122
  if (sb==NULL) {
123
    _assert(root_superblock!=NULL);
124
    root_superblock=NULL;
125
    __fs_mutex_unlock(&mutex);
126
    return;
127
  }
128
  _assert(root_superblock==NULL);
129
  __fs_mutex_unlock(&mutex);
130
  root_superblock=sb;
131
}
132
 
133
/* --- */
134
 
135
int super_incbusy(struct super_block *sb)
136
{
137
  int ret=-1;
138
 
139
  _assert(sb>=sbs&&sb<sbs+MAXSUPERBLOCKS);
140
 
141
  __fs_mutex_lock(&mutex);
142
 
143
  if (sb->sb_blocked==0) {
144
    ret=0;
145
    sb->sb_busycount++;
146
  }
147
 
148
  __fs_mutex_unlock(&mutex);
149
 
150
  return ret;
151
}
152
 
153
void super_decbusy(struct super_block *sb)
154
{
155
  _assert(sb>=sbs&&sb<sbs+MAXSUPERBLOCKS);
156
 
157
  __fs_mutex_lock(&mutex);
158
 
159
  _assert(sb->sb_busycount>0);
160
  _assert(sb->sb_blocked==0);
161
 
162
  sb->sb_busycount--;
163
 
164
  __fs_mutex_unlock(&mutex);
165
}
166
 
167
struct super_block *super_aquire(__dev_t dev)
168
{
169
  struct super_block *ptr=NULL;
170
  int i;
171
 
172
  __fs_mutex_lock(&mutex);
173
 
174
  for (i=0;i<MAXSUPERBLOCKS;i++) {
175
    if (sbs[i].sb_used==1&&sbs[i].sb_dev==dev) {
176
      if (sbs[i].sb_blocked==1||sbs[i].sb_busycount!=0) break;      
177
      sbs[i].sb_blocked=1;
178
      ptr=sbs+i;
179
      break;
180
    }
181
  }
182
  __fs_mutex_unlock(&mutex);
183
  return ptr;
184
}
185
 
186
void super_release(struct super_block *sb)
187
{
188
  _assert(sb>=sbs&&sb<sbs+MAXSUPERBLOCKS);
189
  __fs_mutex_lock(&mutex);
190
  _assert(sb->sb_used==1&&sb->sb_blocked==1);
191
  sb->sb_blocked=0;
192
  __fs_mutex_unlock(&mutex);
193
}
194
 
195
/* -- */
196
 
197
void super_insertintotree(struct super_block *sb, struct super_block *psb)
198
{
199
  __fs_mutex_lock(&mutex);
200
  sb->sb_parent=psb;
201
  sb->sb_next=psb->sb_childs;
202
  sb->sb_childs=NULL;
203
  psb->sb_childs=sb;
204
  __fs_mutex_unlock(&mutex);
205
}
206
 
207
void super_removefromtree(struct super_block *sb)
208
{
209
  struct super_block *ptr,*prev;
210
  ptr=sb->sb_parent->sb_childs;
211
  prev=NULL;
212
  __fs_mutex_lock(&mutex);
213
  while (ptr!=sb) {
214
    prev=ptr;
215
    ptr=ptr->sb_next;
216
    _assert(ptr!=NULL);
217
  }
218
  if (prev!=NULL) prev->sb_next=sb->sb_next;
219
  else sb->sb_parent->sb_childs=sb->sb_next;
220
  __fs_mutex_unlock(&mutex);
221
}
222
 
223
static int visittree(struct super_block *sb,int(*func)(__dev_t))
224
{
225
  struct super_block *ptr;
226
  ptr=sb->sb_childs;
227
  while (ptr!=NULL) {
228
    if (visittree(ptr,func)) return -1;
229
    ptr=ptr->sb_next;
230
  }
231
  return (*func)(sb->sb_dev);
232
}
233
 
234
/* can be called only during shutdown!
235
 * (there must be no lock on superblocks tree during shutdown)
236
 * (the shutdown function is responsable not to call the
237
 * insert/remove_to/from tree functions)
238
 */
239
 
240
int super_enumdevice(int(*func)(__dev_t))
241
{
242
  int res;
243
  res=visittree(root_superblock,func);
244
  return res;
245
}