This is missing.c in view mode; [Download] [Up]
/*
* Name: missing.c
* Description: Functions that are "missing" from the lowlevel interface to
* the filesystems.
* Author: Christian Starkjohann <cs@hal.kph.tuwien.ac.at>
* Date: 1996-11-14
* Copyright: GNU-GPL
* Tabsize: 4
*/
#include <asm/page.h>
#include <linux/tasks.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include "my_defines.h"
#include "cache.h"
/* ------------------------------------------------------------------------- */
extern void *malloc(unsigned long size);
extern void free(void *obj);
extern long lseek(int fd, long offset, int whence);
extern int read(int fd, void *buffer, int len);
extern int write(int fd, void *buffer, int len);
extern void perror(const char *s);
extern void bzero(void *block, int len);
/* ------------------------------------------------------------------------- */
#define DPRINTF(arg) if(debug_mode & DEBUG_MISSING) dprintf arg
/* ------------------------------------------------------------------------- */
struct task_struct *current_set[NR_CPUS];
struct super_block super_blocks[NR_SUPER];
int my_blocksize = 512;
/* ------------------------------------------------------------------------- */
unsigned long __get_free_pages(int priority, unsigned long gfporder, int dma)
{
return (unsigned long)malloc(PAGE_SIZE);
}
/* ------------------------------------------------------------------------- */
void free_pages(unsigned long addr, unsigned long order)
{
free((void *)addr);
}
/* ------------------------------------------------------------------------- */
int permission(struct inode *i, int may_this)
{
/* leave a dummy for now. maybe nfs does the checking?
* i->i_mode
* #define MAY_EXEC 1
* #define MAY_WRITE 2
* #define MAY_READ 4
*/
return 0;
}
/* ------------------------------------------------------------------------- */
void unlock_buffer(struct buffer_head *bh)
{
clear_bit(BH_Lock, &bh->b_state);
}
/* ------------------------------------------------------------------------- */
/*
* struct file_operations {
* int (*lseek) (struct inode *, struct file *, off_t, int);
* int (*read) (struct inode *, struct file *, char *, int);
* int (*write) (struct inode *, struct file *, const char *, int);
* int (*readdir) (struct inode *, struct file *, void *, filldir_t);
* int (*select) (struct inode *, struct file *, int, select_table *);
* int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
* int (*mmap) (struct inode *, struct file *, struct vm_area_struct *);
* int (*open) (struct inode *, struct file *);
* void (*release) (struct inode *, struct file *);
* int (*fsync) (struct inode *, struct file *);
* int (*fasync) (struct inode *, struct file *, int);
* int (*check_media_change) (kdev_t dev);
* int (*revalidate) (kdev_t dev);
* };
* We don't want to support any blockdevice functions for now.
*/
struct file_operations *get_blkfops(unsigned int rdev)
{
static struct file_operations fops = {NULL};
return &fops;
}
/* ------------------------------------------------------------------------- */
void ll_rw_block(int rw, int count, struct buffer_head * bh[])
{
int i;
unsigned long offset;
extern unsigned long part_offset;
extern unsigned long part_size;
for(i=0;i<count;i++){
if(bh[i]->b_size != my_blocksize){
fatal_error("** ll_rw_block: blocksize is %d (should be %d)\n",
(int)bh[i]->b_size, my_blocksize);
return;
}
if((bh[i]->b_blocknr + part_offset/my_blocksize)
>= 0x00800000/my_blocksize*512){
fatal_error("** ll_rw_block: overflow in offset arithmetic\n");
return;
}
if(bh[i]->b_blocknr * my_blocksize + bh[i]->b_size > part_size){
fatal_error("** access to sectors outside parition (%ld)!\n",
bh[i]->b_blocknr);
return;
}
offset = bh[i]->b_blocknr * my_blocksize + part_offset;
switch(rw){
case READ:
case READA:
DPRINTF(("reading block=%ld size=%ld\n",
bh[i]->b_blocknr, bh[i]->b_size));
cached_read(offset, bh[i]->b_data);
break;
case WRITE:
case WRITEA:
DPRINTF(("*** writing block=%ld size=%ld\n",
bh[i]->b_blocknr, bh[i]->b_size));
cached_write(offset, bh[i]->b_data);
clear_bit(BH_Dirty, &bh[i]->b_state);
break;
default:
eprintf("ll_rw_block(mode=%d) unknown mode!\n", rw);
}
set_bit(BH_Uptodate, &bh[i]->b_state);
}
}
/* ------------------------------------------------------------------------- */
int generic_file_read(struct inode *inode, struct file *fp, char *buf, int len)
{
int (*bmap) (struct inode *,int);
struct buffer_head *bh;
int offs, l, b, block, error = 0;
int pos = fp->f_pos;
bmap = inode->i_op->bmap;
if(bmap == NULL){
return -EPERM;
}
block = pos / my_blocksize;
offs = pos - block * my_blocksize;
l = my_blocksize - offs;
while(len > 0){
if(l > len)
l = len;
b = bmap(inode, block);
if(b != 0){
if((bh = bread(inode->i_dev, b, my_blocksize)) == NULL){
error = -EIO;
break;
}
memcpy(buf, bh->b_data + offs, l);
brelse(bh);
}else{
bzero(buf, l);
}
block ++;
buf += l;
error += l; /* count bytes read */
len -= l;
offs = 0;
l = my_blocksize;
}
return error;
}
/* ------------------------------------------------------------------------- */
void set_blocksize(kdev_t dev, int size)
{
DPRINTF(("set_blocksize(size=%d)\n", size));
my_blocksize = size;
cache_set_bsize(size);
}
/* ------------------------------------------------------------------------- */
void missing_regular(void)
{
}
/* ------------------------------------------------------------------------- */
void set_current_ids(int uid, int gid)
{
current->uid = uid;
current->gid = gid;
current->fsuid = uid;
current->fsgid = gid;
}
/* ------------------------------------------------------------------------- */
void missing_init(void)
{
static struct task_struct my_task;
static struct fs_struct my_fs;
static struct mm_struct my_mm;
static struct vm_area_struct vma;
static struct files_struct my_files;
current_set[0] = &my_task;
current->rlim[RLIMIT_NOFILE].rlim_cur = 256;
current->rlim[RLIMIT_NOFILE].rlim_max = 256;
current->rlim[RLIMIT_FSIZE].rlim_cur = 2147483647;
current->rlim[RLIMIT_FSIZE].rlim_max = 2147483647;
current->fs = &my_fs;
current->mm = &my_mm;
my_mm.mmap_avl = my_mm.mmap = &vma;
vma.vm_mm = &my_mm;
vma.vm_start = 0;
vma.vm_end = 0x7fffffffUL;
vma.vm_flags = VM_READ | VM_WRITE | VM_EXEC;
current->files = &my_files;
}
/* ------------------------------------------------------------------------- */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.