home *** CD-ROM | disk | FTP | other *** search
- /*
- * 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;
- }
-
- /* ------------------------------------------------------------------------- */
-