Subversion Repositories shark

Rev

Rev 3 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * Project: HARTIK (HA-rd R-eal TI-me K-ernel)
 *
 * Coordinators: Giorgio Buttazzo <giorgio@sssup.it>
 *               Gerardo Lamastra <gerardo@sssup.it>
 *
 * Authors     : Massimiliano Giorgi <massy@hartik.sssup.it>
 * (see authors.txt for full list of hartik's authors)
 *
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
 *
 * http://www.sssup.it
 * http://retis.sssup.it
 * http://hartik.sssup.it 
 */

/*
 * Copyright (C) 1999 Massimiliano Giorgi
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

/*
 * CVS :        $Id: super.ori,v 1.1.1.1 2002-03-29 14:12:50 pj Exp $
 *
 * File:        $File$
 * Revision:    $Revision: 1.1.1.1 $
 * Last update: $Date: 2002-03-29 14:12:50 $
 */

#include <fs/sysmacro.h>
#include <fs/util.h>
#include <fs/major.h>
#include <fs/fsinit.h>
#include <fs/bdev.h>
#include <fs/fsind.h>
#include <fs/mount.h>
#include <fs/assert.h>

#include "mutex.h"
#include "fs.h"
#include "super.h"

#define MAXSUPERBLOCKS 8
static __fs_mutex_t mutex;
static __fs_mutex_t mutexsb;
static struct super_block sbs[MAXSUPERBLOCKS];

static struct super_block *root_superblock=NULL;

int super_init(void)
{
  int i;
  
  __fs_mutex_init(&mutex);
  __fs_mutex_init(&mutexsb);

  for (i=0;i<MAXSUPERBLOCKS;i++) {
    memset(sbs+i,0,sizeof(struct super_block));
    mount_std_parms(sbs[i].sb_mopts);
    sbs[i].sb_busycount=0;
    sbs[i].sb_used=0;
    sbs[i].sb_blocked=0;
  }

  return 0;
}

struct super_block *super_getblock(void)
{
  struct super_block *ptr=NULL;
  int i;

  __fs_mutex_lock(&mutexsb);
  for (i=0;i<MAXSUPERBLOCKS;i++) 
    if (!sbs[i].sb_used) {
      sbs[i].sb_used=1;
      sbs[i].sb_blocked=1;
      sbs[i].sb_busycount=0;
      ptr=sbs+i;
      break;
    }
  __fs_mutex_unlock(&mutexsb);

  return ptr;
}

void super_freeblock(struct super_block *ptr)
{
  __fs_mutex_lock(&mutexsb);
  assert(ptr->sb_used==1);
  assert(ptr->sb_blocked==1);
  assert(ptr->sb_busycount==0);
  ptr->sb_used=0;
  __fs_mutex_unlock(&mutexsb);
}

void super_enumdevice(int(*func)(__dev_t))
{
  int i;
  //__fs_mutex_lock(&mutexsb);
  for (i=0;i<MAXSUPERBLOCKS;i++) 
    if (!sbs[i].sb_used) {
      sbs[i].sb_used=1;
      (*func)(sbs[i].sb_dev);
    }
  //__fs_mutex_unlock(&mutexsb);  
}

/* --- */

struct super_block *get_root_superblock(void)
{
  assert(root_superblock!=NULL);
  return root_superblock;
}

void set_root_superblock(struct super_block *sb)
{
  assert(root_superblock==NULL);
  root_superblock=sb;
}

/* --- */

int super_incbusy(struct super_block *sb)
{
  int ret=-1;
  
  assert(sb>=sbs&&sb<sbs+MAXSUPERBLOCKS);
  
  __fs_mutex_lock(&mutex);
  
  if (sb->sb_blocked==0) {
    ret=0;
    sb->sb_busycount++;
  }
  
  __fs_mutex_unlock(&mutex);
  
  return ret;
}

void super_decbusy(struct super_block *sb)
{
  assert(sb>=sbs&&sb<sbs+MAXSUPERBLOCKS);
  
  __fs_mutex_lock(&mutex);
  
  assert(sb->sb_busycount>0);
  assert(sb->sb_blocked==0);

  sb->sb_busycount--;
  
  __fs_mutex_unlock(&mutex);
}

struct super_block *super_aquire(__dev_t dev)
{
  struct super_block *ptr=NULL;
  int i;
  
  __fs_mutex_lock(&mutex);
  
  for (i=0;i<MAXSUPERBLOCKS;i++) {
    if (sbs[i].sb_used==1&&sbs[i].sb_dev==dev) {
      if (sbs[i].sb_blocked==1||sbs[i].sb_busycount!=0) break;      
      sbs[i].sb_blocked=1;
      ptr=sbs+i;
      break;
    }
  }
  __fs_mutex_unlock(&mutex);
  return ptr;
}

void super_release(struct super_block *sb)
{
  assert(sb>=sbs&&sb<sbs+MAXSUPERBLOCKS);
  __fs_mutex_lock(&mutex);
  assert(sb->sb_used==1&&sb->sb_blocked==1);
  sb->sb_blocked=0;
  __fs_mutex_unlock(&mutex);
}