OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [fs/] [file_table.c] - Rev 1777

Go to most recent revision | Compare with Previous | Blame | View Log

/*
 *  linux/fs/file_table.c
 *
 *  Copyright (C) 1991, 1992  Linus Torvalds
 */
 
#include <linux/config.h>
#include <linux/stddef.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/mm.h>
 
/*
 * first_file points to a doubly linked list of all file structures in
 *            the system.
 * nr_files   holds the length of this list.
 */
struct file * first_file = NULL;
int nr_files = 0;
int max_files = NR_FILE;
 
/*
 * Insert a new file structure at the head of the list of available ones.
 */
static inline void insert_file_free(struct file *file)
{
	struct file *next, *prev;
 
	next = first_file;
	first_file = file;
	file->f_count = 0;
	prev = next->f_prev;
	file->f_next = next;
	next->f_prev = file;
	file->f_prev = prev;
	prev->f_next = file;
}
 
/*
 * Remove a file structure from the list of available ones.
 */
static inline void remove_file_free(struct file *file)
{
	struct file *next, *prev;
 
	next = file->f_next;
	prev = file->f_prev;
	file->f_next = file->f_prev = NULL;
	if (first_file == file)
		first_file = next;
	next->f_prev = prev;
	prev->f_next = next;
}
 
/*
 * Insert a file structure at the end of the list of available ones.
 */
static inline void put_last_free(struct file *file)
{
	struct file *next, *prev;
 
	next = first_file;
	file->f_next = next;
	prev = next->f_prev;
	next->f_prev = file;
	file->f_prev = prev;
	prev->f_next = file;
}
 
/*
 * Allocate a new memory page for file structures and
 * insert the new structures into the global list.
 * Returns 0, if there is no more memory, 1 otherwise.
 */
static int grow_files(void)
{
	struct file * file;
	int i;
 
	/*
	 * We don't have to clear the page because we only look into
	 * f_count, f_prev and f_next and they get initialized in
	 * insert_file_free.  The rest of the file structure is cleared
	 * by get_empty_filp before it is returned.
	 */
	file = (struct file *) __get_free_page(GFP_KERNEL);
 
	if (!file)
		return 0;
 
	nr_files += i = PAGE_SIZE/sizeof(struct file);
 
	if (!first_file)
		file->f_count = 0,
		file->f_next = file->f_prev = first_file = file++,
		i--;
 
	for (; i ; i--)
		insert_file_free(file++);
 
	return 1;
}
 
unsigned long file_table_init(unsigned long start, unsigned long end)
{
	return start;
}
 
/*
 * Find an unused file structure and return a pointer to it.
 * Returns NULL, if there are no more free file structures or
 * we run out of memory.
 */
struct file * get_empty_filp(void)
{
	int i;
	int max = max_files;
	struct file * f;
 
	/*
	 * Reserve a few files for the super-user..
	 */
	if (current->euid)
		max -= 10;
 
	/* if the return is taken, we are in deep trouble */
	if (!first_file && !grow_files())
		return NULL;
 
	do {
		for (f = first_file, i=0; i < nr_files; i++, f = f->f_next)
			if (!f->f_count) {
				/* The f_next pointer is followed by the f_prev pointer */
				memset(f, 0, offsetof(struct file, f_next));
				memset(&f->f_prev + 1, 0, sizeof(*f) - sizeof(f->f_prev) - offsetof(struct file, f_prev));
				f->f_count = 1;
				f->f_version = ++event;
				first_file = f->f_next;
				return f;
			}
	} while (nr_files < max && grow_files());
 
	return NULL;
}
 
#ifdef CONFIG_QUOTA
 
void add_dquot_ref(kdev_t dev, short type)
{
	struct file *filp;
	int cnt;
 
	for (filp = first_file, cnt = 0; cnt < nr_files; cnt++, filp = filp->f_next) {
		if (!filp->f_count || !filp->f_inode || filp->f_inode->i_dev != dev)
			continue;
		if (filp->f_mode & FMODE_WRITE && filp->f_inode->i_sb->dq_op) {
			filp->f_inode->i_sb->dq_op->initialize(filp->f_inode, type);
			filp->f_inode->i_flags |= S_WRITE;
		}
	}
}
 
void reset_dquot_ptrs(kdev_t dev, short type)
{
	struct file *filp;
	int cnt;
 
	for (filp = first_file, cnt = 0; cnt < nr_files; cnt++, filp = filp->f_next) {
		if (!filp->f_count || !filp->f_inode || filp->f_inode->i_dev != dev)
			continue;
		if (IS_WRITABLE(filp->f_inode)) {
			filp->f_inode->i_dquot[type] = NODQUOT;
			filp->f_inode->i_flags &= ~S_WRITE;
		}
	}
}
 
#endif
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.