ftp.nice.ch/pub/next/unix/disk/vmount.0.6a.s.tar.gz#/vmount.0.6a.s/missing.c

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.